@dbx-tools/appkit-mastra 0.6.9 → 0.6.11

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.
@@ -1,19 +1,24 @@
1
1
  /**
2
2
  * Startup provisioning of remote Agent-Skill sources for a Mastra workspace.
3
3
  *
4
- * A {@link RemoteSkillSource} names WHERE a `SKILL.md` tree comes from - a
5
- * GitHub `owner/repo`, any git / GitLab URL, or a direct download URL - and
6
- * optional per-source policy. {@link provisionRemoteSkills} materializes every
7
- * source into a local `SKILL.md` tree at app boot and returns the directories
8
- * to hand Mastra as extra skill scan paths.
4
+ * A {@link RemoteSkillSource} names WHERE a `SKILL.md` tree comes from - the
5
+ * {@link AITOOLS_SOURCE} constant, a GitHub `owner/repo`, any git / GitLab URL,
6
+ * or a direct download URL - and optional per-source policy.
7
+ * {@link provisionRemoteSkills} materializes every source into a local
8
+ * `SKILL.md` tree at app boot and returns the directories to hand Mastra as
9
+ * extra skill scan paths.
9
10
  *
10
11
  * Resolution per source, in order:
11
12
  *
12
- * 1. the OPTIONAL `skills` npm CLI (peer dep): if installed, each source is
13
+ * 1. the {@link AITOOLS_SOURCE} constant (`"aitools"`): Databricks' own skill
14
+ * set, read straight from the public repo the `databricks aitools` CLI
15
+ * sources from. No CLI, no Databricks auth - which is what makes it usable
16
+ * inside a Databricks App container, where the CLI is not installed;
17
+ * 2. the OPTIONAL `skills` npm CLI (peer dep): if installed, each source is
13
18
  * copied into a staging dir with `skills add <source> --agent <dir> --copy`,
14
19
  * which understands every source format the ecosystem does (GitHub
15
20
  * shorthand, git URLs, archive/download URLs);
16
- * 2. otherwise a plain {@link fetch} of the source URL (built with
21
+ * 3. otherwise a plain {@link fetch} of the source URL (built with
17
22
  * {@link net.urlBuilder}), writing the downloaded `SKILL.md` to a staging
18
23
  * dir.
19
24
  *
@@ -27,20 +32,20 @@
27
32
  * discovered by the built-in Assistant-skills mount. Pass `userEmail` (or an
28
33
  * explicit `databricksBasePath`) to target `/Users/<email>/.assistant/skills`
29
34
  * instead. When no Databricks client is resolvable at startup, the tree is
30
- * written to a local temp dir and returned as an extra local skill path for
31
- * the current process.
35
+ * written under {@link localFS.tmpFS} and returned as an extra local skill path
36
+ * for the current process.
32
37
  *
33
38
  * @module
34
39
  */
35
- import { mkdtemp, cp, mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
40
+ import { mkdir, readdir, readFile, rm, stat, writeFile } from "node:fs/promises";
36
41
  import { createRequire } from "node:module";
37
- import { tmpdir } from "node:os";
38
- import { join, posix } from "node:path";
42
+ import { dirname, join, posix } from "node:path";
39
43
  import { appkit } from "@dbx-tools/appkit";
40
- import { spawn } from "@dbx-tools/core";
41
- import { findFiles } from "@dbx-tools/path";
42
- import { error, log, net, string } from "@dbx-tools/shared-core";
43
- import { DatabricksWorkspaceFilesystem } from "./filesystems.js";
44
+ import { exec } from "@dbx-tools/core";
45
+ import { DatabricksFileSystem } from "@dbx-tools/databricks";
46
+ import { localFS } from "@dbx-tools/fs";
47
+ import { find } from "@dbx-tools/path";
48
+ import { error, hash, json, log, net, object, string } from "@dbx-tools/shared-core";
44
49
  const logger = log.logger("mastra/remote-skills");
45
50
  /** Shared Assistant skills tree in the Databricks workspace (default target). */
46
51
  const ASSISTANT_SHARED_SKILLS_PATH = "/Workspace/.assistant/skills";
@@ -54,36 +59,72 @@ const SKILLS_CLI_AGENT = "agents";
54
59
  const SKILLS_CLI_LAYOUT = [".agents", "skills"];
55
60
  /** Cap on a direct-fetch download body, matching the `skills` CLI default. */
56
61
  const DEFAULT_MAX_DOWNLOAD_BYTES = 10 * 1024 * 1024;
62
+ /** Stable temp directory holding one rebuilt skill tree per remote source. */
63
+ const LOCAL_SKILLS_DIR = "mastra-local-skills";
64
+ /* ------------------------------ AI Tools ------------------------------ */
65
+ /**
66
+ * Source constant selecting Databricks' own AI Tools skill set.
67
+ *
68
+ * @example
69
+ * mastra({ remoteSkills: "aitools" });
70
+ */
71
+ export const AITOOLS_SOURCE = "aitools";
72
+ /**
73
+ * The PUBLIC repo `databricks aitools install` sources from. Reading it
74
+ * directly is what lets an app get the same skills the CLI installs without
75
+ * the CLI - which a Databricks App container does not ship.
76
+ */
77
+ const AITOOLS_REPO = "databricks/databricks-agent-skills";
78
+ /** Repo ref the skills are read from. Override per source with `ref`. */
79
+ const AITOOLS_REF = "main";
80
+ /** Skill files downloaded at once; the set is ~30 skills of a few files each. */
81
+ const AITOOLS_CONCURRENCY = 8;
57
82
  /* ------------------------------- helpers ------------------------------- */
58
83
  /** Normalize the `remoteSkills` option into a flat options bag. */
59
84
  export function normalizeRemoteSkillsOption(option) {
60
85
  if (option === undefined)
61
86
  return undefined;
62
- if (typeof option === "string")
63
- return { sources: [option] };
64
- if (Array.isArray(option))
65
- return option.length > 0 ? { sources: option } : undefined;
66
- if (isProvisionOptions(option)) {
67
- const sources = Array.isArray(option.sources) ? option.sources : [option.sources];
68
- return sources.length > 0 ? { ...option, sources } : undefined;
69
- }
70
- // A lone RemoteSkillSourceOptions object.
71
- return { sources: [option] };
87
+ const bag = isProvisionOptions(option) ? option : undefined;
88
+ const sources = toSourceList(bag ? bag.sources : option);
89
+ // An empty list is the same as no configuration at all.
90
+ if (!object.isOneOrMany(sources))
91
+ return undefined;
92
+ return { ...bag, sources };
72
93
  }
73
94
  /** A `sources`-bearing bag is the top-level options shape, not a single source. */
74
95
  function isProvisionOptions(value) {
75
- return "sources" in value;
96
+ return object.isRecord(value) && "sources" in value;
97
+ }
98
+ /** One source or many, as a plain array. A source is never itself an array. */
99
+ function toSourceList(input) {
100
+ return Array.isArray(input) ? [...input] : [input];
76
101
  }
77
- /** Coerce a source entry to its normalized {@link RemoteSkillSourceOptions}. */
102
+ /** Flatten a source entry - string, `URL`, `{ url }`, or options bag - to a {@link NormalizedSource}. */
78
103
  function toSourceOptions(source) {
79
- return typeof source === "string" ? { source } : source;
104
+ if (typeof source === "string")
105
+ return { source };
106
+ if (source instanceof URL)
107
+ return { source: source.toString() };
108
+ if ("source" in source)
109
+ return { ...source, source: toSourceString(source.source) };
110
+ return { source: source.url };
111
+ }
112
+ /** A {@link net.UrlLike} as the plain string the staging paths work with. */
113
+ function toSourceString(source) {
114
+ if (typeof source === "string")
115
+ return source;
116
+ return source instanceof URL ? source.toString() : source.url;
117
+ }
118
+ /** True when a source selects the built-in Databricks AI Tools skill set. */
119
+ function isAiToolsSource(source) {
120
+ return source.trim().toLowerCase() === AITOOLS_SOURCE;
80
121
  }
81
122
  /**
82
123
  * Materialize every configured remote skill source at app startup.
83
124
  *
84
125
  * Writes each resolved `SKILL.md` tree to the Databricks user Assistant skills
85
- * folder when a writable workspace is available, else to a local temp dir
86
- * returned in {@link ProvisionedRemoteSkills.localSkillPaths}.
126
+ * folder when a writable workspace is available, else under
127
+ * {@link localFS.tmpFS} returned in {@link ProvisionedRemoteSkills.localSkillPaths}.
87
128
  */
88
129
  export async function provisionRemoteSkills(option) {
89
130
  const options = normalizeRemoteSkillsOption(option);
@@ -94,7 +135,12 @@ export async function provisionRemoteSkills(option) {
94
135
  const client = options.client ?? appkit.tryGetExecutionContext()?.client;
95
136
  const databricksBasePath = resolveDatabricksBasePath(options, client);
96
137
  const destination = databricksBasePath
97
- ? new DatabricksWorkspaceFilesystem({ client, basePath: databricksBasePath, readOnly: false })
138
+ ? new DatabricksFileSystem({
139
+ client: client,
140
+ root: databricksBasePath,
141
+ readOnly: false,
142
+ createRoot: true,
143
+ })
98
144
  : undefined;
99
145
  const localSkillPaths = [];
100
146
  const skillNames = [];
@@ -105,18 +151,18 @@ export async function provisionRemoteSkills(option) {
105
151
  const sourceOptions = toSourceOptions(entry);
106
152
  const failOnError = sourceOptions.failOnError ?? failDefault;
107
153
  try {
108
- staging ??= await mkdtemp(join(tmpdir(), "mastra-remote-skills-"));
109
- const stagedDir = await stageSource(sourceOptions, staging, options);
154
+ staging ??= await initializedScratch("mastra-remote-skills");
155
+ const stagedDir = await stageSource(sourceOptions, staging.root, options);
110
156
  const staged = await collectSkillDirs(stagedDir);
111
157
  if (staged.length === 0) {
112
158
  throw new Error(`no SKILL.md found for source "${sourceOptions.source}"`);
113
159
  }
114
160
  if (destination && databricksBasePath) {
115
- await uploadSkillDirs(destination, staged);
161
+ await copySkillDirs(destination, staged);
116
162
  skillNames.push(...staged.map((dir) => dir.name));
117
163
  }
118
164
  else {
119
- const localDir = await persistLocally(staged);
165
+ const localDir = await persistLocally(sourceOptions.source, staged);
120
166
  localSkillPaths.push(localDir);
121
167
  skillNames.push(...staged.map((dir) => dir.name));
122
168
  }
@@ -138,8 +184,9 @@ export async function provisionRemoteSkills(option) {
138
184
  }
139
185
  }
140
186
  finally {
141
- if (staging)
142
- await rm(staging, { recursive: true, force: true }).catch(() => undefined);
187
+ if (staging) {
188
+ await rm(staging.root, { recursive: true, force: true }).catch(() => undefined);
189
+ }
143
190
  }
144
191
  return { localSkillPaths, databricksBasePath, skillNames };
145
192
  }
@@ -156,16 +203,65 @@ function resolveDatabricksBasePath(options, client) {
156
203
  return email ? userAssistantSkillsPath(email) : ASSISTANT_SHARED_SKILLS_PATH;
157
204
  }
158
205
  /**
159
- * Stage one source into a fresh dir under `staging`, preferring the optional
206
+ * Stage one source into a fresh dir under `stagingRoot`, preferring the optional
160
207
  * `skills` CLI and falling back to a direct fetch.
161
208
  */
162
- async function stageSource(sourceOptions, staging, options) {
163
- const target = await mkdtemp(join(staging, "src-"));
209
+ async function stageSource(sourceOptions, stagingRoot, options) {
210
+ const target = join(stagingRoot, `src-${hash.id()}`);
211
+ await mkdir(target, { recursive: true });
212
+ // AI Tools resolves from a known repo layout, so it never needs the CLI.
213
+ if (isAiToolsSource(sourceOptions.source))
214
+ return stageAiTools(sourceOptions, target, options);
164
215
  const viaCli = await stageViaSkillsCli(sourceOptions, target);
165
216
  if (viaCli)
166
217
  return viaCli;
167
218
  return stageViaFetch(sourceOptions, target, options);
168
219
  }
220
+ /**
221
+ * Materialize the Databricks AI Tools skills into `target`.
222
+ *
223
+ * Reads the repo's own generated `manifest.json` (which names each skill's
224
+ * files and whether it lives under `skills/` or `experimental/`) and downloads
225
+ * them - the same thing `databricks aitools install` does, minus the CLI and
226
+ * minus any Databricks auth, since the repo is public.
227
+ */
228
+ async function stageAiTools(sourceOptions, target, options) {
229
+ const maxBytes = resolveMaxBytes(sourceOptions, options);
230
+ const ref = string.trimToNull(sourceOptions.ref) ?? AITOOLS_REF;
231
+ const manifest = json.parse((await download(aiToolsRawUrl(ref, "manifest.json"), maxBytes)).toString("utf8"), undefined);
232
+ const wanted = new Set(string.parseList(sourceOptions.skills));
233
+ const selected = Object.entries(manifest?.skills ?? {}).filter(([name, entry]) => wanted.size > 0
234
+ ? wanted.has(name)
235
+ : entry.repo_dir !== "experimental" || sourceOptions.experimental === true);
236
+ if (selected.length === 0) {
237
+ throw new Error(`no matching skills in ${AITOOLS_REPO}@${ref}`);
238
+ }
239
+ const files = selected.flatMap(([name, entry]) => (entry.files ?? []).map((file) => ({
240
+ url: aiToolsRawUrl(ref, `${entry.repo_dir ?? "skills"}/${name}/${file}`),
241
+ path: join(target, name, ...file.split("/")),
242
+ })));
243
+ await mapConcurrent(files, AITOOLS_CONCURRENCY, async (item) => {
244
+ const body = await download(item.url, maxBytes);
245
+ await mkdir(dirname(item.path), { recursive: true });
246
+ await writeFile(item.path, body);
247
+ });
248
+ logger.debug("aitools:staged", { ref, skills: selected.length, files: files.length });
249
+ return target;
250
+ }
251
+ /** Raw-content URL for a path in the AI Tools repo at `ref`. */
252
+ function aiToolsRawUrl(ref, path) {
253
+ return `https://raw.githubusercontent.com/${AITOOLS_REPO}/${ref}/${path}`;
254
+ }
255
+ /** Run `worker` over `items`, at most `limit` in flight. */
256
+ async function mapConcurrent(items, limit, worker) {
257
+ let cursor = 0;
258
+ const runners = Array.from({ length: Math.min(limit, items.length) }, async () => {
259
+ while (cursor < items.length) {
260
+ await worker(items[cursor++]);
261
+ }
262
+ });
263
+ await Promise.all(runners);
264
+ }
169
265
  /**
170
266
  * Copy a source into `target` with the `skills` CLI when it is installed.
171
267
  * Returns the dir holding the copied `SKILL.md` trees, or `undefined` when the
@@ -189,7 +285,7 @@ async function stageViaSkillsCli(sourceOptions, target) {
189
285
  }
190
286
  if (string.parseList(sourceOptions.skills).length === 0)
191
287
  args.push("--skill", "*");
192
- const result = await spawn(cli.command, args, {
288
+ const result = await exec.spawn(cli.command, args, {
193
289
  cwd: target,
194
290
  stdout: "capture",
195
291
  stderr: "capture",
@@ -227,21 +323,29 @@ async function stageViaFetch(sourceOptions, target, options) {
227
323
  if (!url) {
228
324
  throw new Error(`source "${sourceOptions.source}" is not a URL and the optional "skills" package is not installed`);
229
325
  }
230
- const maxBytes = sourceOptions.maxDownloadBytes ?? options.maxDownloadBytes ?? DEFAULT_MAX_DOWNLOAD_BYTES;
231
- const response = await fetch(url.toString());
232
- if (!response.ok) {
233
- throw new Error(`download failed: ${response.status} ${response.statusText} (${url.toString()})`);
234
- }
235
- const buffer = Buffer.from(await response.arrayBuffer());
236
- if (buffer.byteLength > maxBytes) {
237
- throw new Error(`download exceeds ${maxBytes} bytes (${url.toString()})`);
238
- }
326
+ const buffer = await download(url.toString(), resolveMaxBytes(sourceOptions, options));
239
327
  const name = string.toSlug(deriveSkillName(url.toString())) || "remote-skill";
240
328
  const skillDir = join(target, name);
241
329
  await mkdir(skillDir, { recursive: true });
242
330
  await writeFile(join(skillDir, "SKILL.md"), buffer);
243
331
  return target;
244
332
  }
333
+ /** The effective download ceiling: per-source, then top-level, then the default. */
334
+ function resolveMaxBytes(sourceOptions, options) {
335
+ return sourceOptions.maxDownloadBytes ?? options.maxDownloadBytes ?? DEFAULT_MAX_DOWNLOAD_BYTES;
336
+ }
337
+ /** GET a URL, failing loudly on a non-2xx status or an oversized body. */
338
+ async function download(url, maxBytes) {
339
+ const response = await fetch(url);
340
+ if (!response.ok) {
341
+ throw new Error(`download failed: ${response.status} ${response.statusText} (${url})`);
342
+ }
343
+ const buffer = Buffer.from(await response.arrayBuffer());
344
+ if (buffer.byteLength > maxBytes) {
345
+ throw new Error(`download exceeds ${maxBytes} bytes (${url})`);
346
+ }
347
+ return buffer;
348
+ }
245
349
  /** Derive a skill directory name from a download URL's last path segment. */
246
350
  function deriveSkillName(urlString) {
247
351
  const url = net.urlBuilder(urlString);
@@ -270,24 +374,43 @@ async function collectSkillDirs(root) {
270
374
  }
271
375
  return dirs;
272
376
  }
273
- /** Upload each staged skill directory into the Databricks destination tree. */
274
- async function uploadSkillDirs(destination, dirs) {
275
- await destination.init?.();
377
+ /**
378
+ * Copy every staged skill directory into {@link destination}, preserving the
379
+ * `<skill>/<relative>` layout. The destination is just a {@link FileSystem},
380
+ * so the Databricks Assistant tree and the local fallback share one copier.
381
+ */
382
+ async function copySkillDirs(destination, dirs) {
383
+ await destination.init();
276
384
  for (const dir of dirs) {
277
- for (const relative of findFiles("**/*", { cwd: dir.absolutePath, nodir: true })) {
385
+ for (const relative of find.findFiles("**/*", { cwd: dir.absolutePath, nodir: true })) {
278
386
  const buffer = await readFile(join(dir.absolutePath, relative));
279
- const remotePath = posix.join("/", dir.name, relative.split(/[\\/]/).join("/"));
280
- await destination.writeFile(remotePath, buffer, { overwrite: true });
387
+ const skillPath = posix.join(dir.name, relative.split(/[\\/]/).join("/"));
388
+ await destination.writeFile(skillPath, buffer, { overwrite: true });
281
389
  }
282
390
  }
283
391
  }
284
- /** Copy staged skill dirs into a persistent local temp dir; return its path. */
285
- async function persistLocally(dirs) {
286
- const base = await mkdtemp(join(tmpdir(), "mastra-local-skills-"));
287
- for (const dir of dirs) {
288
- await cp(dir.absolutePath, join(base, dir.name), { recursive: true });
289
- }
290
- return base;
392
+ /**
393
+ * Copy staged skill dirs into a STABLE local tree keyed by the source, and
394
+ * return its root path.
395
+ *
396
+ * A given source resolves to the same content on almost every boot, so each
397
+ * one owns a directory named for its {@link hash.fnvHash} rather than leaving
398
+ * a fresh scratch dir behind per restart. Keying on the source (not the
399
+ * content) is what keeps two different sources from overwriting each other.
400
+ */
401
+ async function persistLocally(source, dirs) {
402
+ const stable = await localFS.rebuildFS(`${LOCAL_SKILLS_DIR}/${hash.fnvHash(source)}`, (scratch) => copySkillDirs(scratch, dirs));
403
+ return stable.root;
404
+ }
405
+ /**
406
+ * A scratch filesystem whose root exists on disk, for the paths that hand a
407
+ * real directory to `node:fs` or a child process rather than going through
408
+ * the {@link FileSystem} API.
409
+ */
410
+ async function initializedScratch(prefix) {
411
+ const scratch = localFS.scratchFS(prefix);
412
+ await scratch.init();
413
+ return scratch;
291
414
  }
292
415
  /** Best-effort existence check. */
293
416
  async function pathExists(path) {
@@ -299,4 +422,4 @@ async function pathExists(path) {
299
422
  return false;
300
423
  }
301
424
  }
302
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLXNraWxscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZW1vdGUtc2tpbGxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQ0c7QUFFSCxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQzlGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUNqQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFM0MsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM1QyxPQUFPLEVBQUUsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFakUsT0FBTyxFQUFFLDZCQUE2QixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFakUsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBRWxELGlGQUFpRjtBQUNqRixNQUFNLDRCQUE0QixHQUFHLDhCQUE4QixDQUFDO0FBRXBFLGlFQUFpRTtBQUNqRSxTQUFTLHVCQUF1QixDQUFDLFNBQWlCO0lBQ2hELE9BQU8sVUFBVSxTQUFTLENBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDO0FBQ3hELENBQUM7QUFFRCwyRUFBMkU7QUFDM0UsTUFBTSxnQkFBZ0IsR0FBRyxRQUFR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LFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDaEUsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ2hGLE1BQU0sV0FBVyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkUsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLEtBQUssVUFBVSxjQUFjLENBQUMsSUFBc0I7SUFDbEQsTUFBTSxJQUFJLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLHNCQUFzQixDQUFDLENBQUMsQ0FBQztJQUNuRSxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN4RSxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQsbUNBQW1DO0FBQ25DLEtBQUssVUFBVSxVQUFVLENBQUMsSUFBWTtJQUNwQyxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFydHVwIHByb3Zpc2lvbmluZyBvZiByZW1vdGUgQWdlbnQtU2tpbGwgc291cmNlcyBmb3IgYSBNYXN0cmEgd29ya3NwYWNlLlxuICpcbiAqIEEge0BsaW5rIFJlbW90ZVNraWxsU291cmNlfSBuYW1lcyBXSEVSRSBhIGBTS0lMTC5tZGAgdHJlZSBjb21lcyBmcm9tIC0gYVxuICogR2l0SHViIGBvd25lci9yZXBvYCwgYW55IGdpdCAvIEdpdExhYiBVUkwsIG9yIGEgZGlyZWN0IGRvd25sb2FkIFVSTCAtIGFuZFxuICogb3B0aW9uYWwgcGVyLXNvdXJjZSBwb2xpY3kuIHtAbGluayBwcm92aXNpb25SZW1vdGVTa2lsbHN9IG1hdGVyaWFsaXplcyBldmVyeVxuICogc291cmNlIGludG8gYSBsb2NhbCBgU0tJTEwubWRgIHRyZWUgYXQgYXBwIGJvb3QgYW5kIHJldHVybnMgdGhlIGRpcmVjdG9yaWVzXG4gKiB0byBoYW5kIE1hc3RyYSBhcyBleHRyYSBza2lsbCBzY2FuIHBhdGhzLlxuICpcbiAqIFJlc29sdXRpb24gcGVyIHNvdXJjZSwgaW4gb3JkZXI6XG4gKlxuICogMS4gdGhlIE9QVElPTkFMIGBza2lsbHNgIG5wbSBDTEkgKHBlZXIgZGVwKTogaWYgaW5zdGFsbGVkLCBlYWNoIHNvdXJjZSBpc1xuICogICAgY29waWVkIGludG8gYSBzdGFnaW5nIGRpciB3aXRoIGBza2lsbHMgYWRkIDxzb3VyY2U+IC0tYWdlbnQgPGRpcj4gLS1jb3B5YCxcbiAqICAgIHdoaWNoIHVuZGVyc3RhbmRzIGV2ZXJ5IHNvdXJjZSBmb3JtYXQgdGhlIGVjb3N5c3RlbSBkb2VzIChHaXRIdWJcbiAqICAgIHNob3J0aGFuZCwgZ2l0IFVSTHMsIGFyY2hpdmUvZG93bmxvYWQgVVJMcyk7XG4gKiAyLiBvdGhlcndpc2UgYSBwbGFpbiB7QGxpbmsgZmV0Y2h9IG9mIHRoZSBzb3VyY2UgVVJMIChidWlsdCB3aXRoXG4gKiAgICB7QGxpbmsgbmV0LnVybEJ1aWxkZXJ9KSwgd3JpdGluZyB0aGUgZG93bmxvYWRlZCBgU0tJTEwubWRgIHRvIGEgc3RhZ2luZ1xuICogICAgZGlyLlxuICpcbiAqIEEgc291cmNlIHRoYXQgcmVzb2x2ZXMgdGhyb3VnaCBuZWl0aGVyIHBhdGggZmFpbHMgYXBwIHN0YXJ0dXAsIHVubGVzcyB0aGVcbiAqIHNvdXJjZSAob3IgdGhlIHRvcC1sZXZlbCBjYWxsKSBzZXRzIGBmYWlsT25FcnJvcjogZmFsc2VgLCBpbiB3aGljaCBjYXNlIGl0IGlzXG4gKiBsb2dnZWQgYW5kIHNraXBwZWQgc28gb25lIGJhZCBzb3VyY2UgbmV2ZXIgdGFrZXMgdGhlIGFwcCBkb3duLlxuICpcbiAqIFRoZSBkZWZhdWx0IGRlc3RpbmF0aW9uIGlzIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBBc3Npc3RhbnQgc2tpbGxzIHRyZWVcbiAqIChgL1dvcmtzcGFjZS8uYXNzaXN0YW50L3NraWxsc2AsIHRoZSBzYW1lIHRyZWUgYSBcInNhdmUgdGhpcyBhcyBhIHNraWxsXCJcbiAqIGFjdGlvbiB3cml0ZXMgdG8pLCBzbyBwcm92aXNpb25lZCBza2lsbHMgcGVyc2lzdCBhY3Jvc3MgcmVzdGFydHMgYW5kIGFyZVxuICogZGlzY292ZXJlZCBieSB0aGUgYnVpbHQtaW4gQXNzaXN0YW50LXNraWxscyBtb3VudC4gUGFzcyBgdXNlckVtYWlsYCAob3IgYW5cbiAqIGV4cGxpY2l0IGBkYXRhYnJpY2tzQmFzZVBhdGhgKSB0byB0YXJnZXQgYC9Vc2Vycy88ZW1haWw+Ly5hc3Npc3RhbnQvc2tpbGxzYFxuICogaW5zdGVhZC4gV2hlbiBubyBEYXRhYnJpY2tzIGNsaWVudCBpcyByZXNvbHZhYmxlIGF0IHN0YXJ0dXAsIHRoZSB0cmVlIGlzXG4gKiB3cml0dGVuIHRvIGEgbG9jYWwgdGVtcCBkaXIgYW5kIHJldHVybmVkIGFzIGFuIGV4dHJhIGxvY2FsIHNraWxsIHBhdGggZm9yXG4gKiB0aGUgY3VycmVudCBwcm9jZXNzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBta2R0ZW1wLCBjcCwgbWtkaXIsIHJlYWRkaXIsIHJlYWRGaWxlLCBybSwgc3RhdCwgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IHRtcGRpciB9IGZyb20gXCJub2RlOm9zXCI7XG5pbXBvcnQgeyBqb2luLCBwb3NpeCB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IGFwcGtpdCB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnRMaWtlIH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgeyBzcGF3biB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGZpbmRGaWxlcyB9IGZyb20gXCJAZGJ4LXRvb2xzL3BhdGhcIjtcbmltcG9ydCB7IGVycm9yLCBsb2csIG5ldCwgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcblxuaW1wb3J0IHsgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW0gfSBmcm9tIFwiLi9maWxlc3lzdGVtcy50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibWFzdHJhL3JlbW90ZS1za2lsbHNcIik7XG5cbi8qKiBTaGFyZWQgQXNzaXN0YW50IHNraWxscyB0cmVlIGluIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSAoZGVmYXVsdCB0YXJnZXQpLiAqL1xuY29uc3QgQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCA9IFwiL1dvcmtzcGFjZS8uYXNzaXN0YW50L3NraWxsc1wiO1xuXG4vKiogQXNzaXN0YW50IHNraWxscyBkaXJlY3RvcnkgZm9yIGEgc3BlY2lmaWMgRGF0YWJyaWNrcyB1c2VyLiAqL1xuZnVuY3Rpb24gdXNlckFzc2lzdGFudFNraWxsc1BhdGgodXNlckVtYWlsOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYC9Vc2Vycy8ke3VzZXJFbWFpbC50cmltKCl9Ly5hc3Npc3RhbnQvc2tpbGxzYDtcbn1cblxuLyoqIG5wbSBhZ2VudCBpZCB0aGUgYHNraWxsc2AgQ0xJIGluc3RhbGxzIGEgYmFyZSBgU0tJTEwubWRgIHRyZWUgdW5kZXIuICovXG5jb25zdCBTS0lMTFNfQ0xJX0FHRU5UID0gXCJhZ2VudHNcIjtcblxuLyoqIFdoZXJlIHRoZSBgc2tpbGxzYCBDTEkgZHJvcHMgYSBwbGFpbiBgU0tJTEwubWRgIHRyZWUgdW5kZXIgYSB0YXJnZXQgZGlyLiAqL1xuY29uc3QgU0tJTExTX0NMSV9MQVlPVVQgPSBbXCIuYWdlbnRzXCIsIFwic2tpbGxzXCJdIGFzIGNvbnN0O1xuXG4vKiogQ2FwIG9uIGEgZGlyZWN0LWZldGNoIGRvd25sb2FkIGJvZHksIG1hdGNoaW5nIHRoZSBgc2tpbGxzYCBDTEkgZGVmYXVsdC4gKi9cbmNvbnN0IERFRkFVTFRfTUFYX0RPV05MT0FEX0JZVEVTID0gMTAgKiAxMDI0ICogMTAyNDtcblxuLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gdHlwZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBPbmUgcmVtb3RlIHNraWxsIHNvdXJjZSBhbmQgaXRzIHBlci1zb3VyY2UgcG9saWN5LlxuICpcbiAqIGBzb3VyY2VgIGlzIGFueXRoaW5nIHRoZSBgc2tpbGxzYCBlY29zeXN0ZW0gdW5kZXJzdGFuZHM6IGEgR2l0SHViXG4gKiBgb3duZXIvcmVwb2Agc2hvcnRoYW5kLCBhIGZ1bGwgR2l0SHViIC8gR2l0TGFiIC8gZ2l0IFVSTCwgb3IgYSBkaXJlY3RcbiAqIGRvd25sb2FkIFVSTCB0byBhIGBTS0lMTC5tZGAgb3IgYXJjaGl2ZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW1vdGVTa2lsbFNvdXJjZU9wdGlvbnMge1xuICAvKiogR2l0SHViIHNob3J0aGFuZCwgZ2l0IC8gR2l0TGFiIFVSTCwgb3IgYSBkaXJlY3QgZG93bmxvYWQgVVJMLiAqL1xuICBzb3VyY2U6IHN0cmluZztcbiAgLyoqIEluc3RhbGwgb25seSB0aGVzZSBza2lsbCBuYW1lcyBmcm9tIHRoZSBzb3VyY2UgKENMSSBwYXRoIG9ubHkpLiAqL1xuICBza2lsbHM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqIE92ZXJyaWRlIHRoZSBieXRlIGNlaWxpbmcgb24gYSBkaXJlY3QtZmV0Y2ggZG93bmxvYWQgZm9yIHRoaXMgc291cmNlLiAqL1xuICBtYXhEb3dubG9hZEJ5dGVzPzogbnVtYmVyO1xuICAvKipcbiAgICogV2hlbiBgZmFsc2VgLCBhIHNvdXJjZSB0aGF0IGZhaWxzIHRvIHJlc29sdmUgaXMgbG9nZ2VkIGFuZCBza2lwcGVkIGluc3RlYWRcbiAgICogb2YgZmFpbGluZyBhcHAgc3RhcnR1cC4gT3ZlcnJpZGVzIHRoZSB0b3AtbGV2ZWwge0BsaW5rIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMuZmFpbE9uRXJyb3J9LlxuICAgKi9cbiAgZmFpbE9uRXJyb3I/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgcmVtb3RlIHNraWxsIHNvdXJjZTogYSBiYXJlIHNvdXJjZSBzdHJpbmcgKEdpdEh1YiBzaG9ydGhhbmQgLyBVUkwpIG9yIGFcbiAqIHtAbGluayBSZW1vdGVTa2lsbFNvdXJjZU9wdGlvbnN9IHdpdGggcGVyLXNvdXJjZSBwb2xpY3kuXG4gKi9cbmV4cG9ydCB0eXBlIFJlbW90ZVNraWxsU291cmNlID0gc3RyaW5nIHwgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zO1xuXG4vKipcbiAqIFRoZSB3b3Jrc3BhY2UgYHJlbW90ZVNraWxsc2Agb3B0aW9uLiBBIHNpbmdsZSBzb3VyY2UsIGEgbGlzdCwgb3IgYVxuICoge0BsaW5rIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnN9IGJhZyB3aGVuIHRvcC1sZXZlbCBwb2xpY3kgaXMgbmVlZGVkLlxuICovXG5leHBvcnQgdHlwZSBSZW1vdGVTa2lsbHNPcHRpb24gPVxuICBSZW1vdGVTa2lsbFNvdXJjZSB8IFJlbW90ZVNraWxsU291cmNlW10gfCBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zO1xuXG4vKiogVG9wLWxldmVsIHJlbW90ZS1za2lsbHMgcHJvdmlzaW9uaW5nIG9wdGlvbnMuICovXG5leHBvcnQgaW50ZXJmYWNlIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMge1xuICAvKiogU291cmNlcyB0byBtYXRlcmlhbGl6ZSBhdCBzdGFydHVwLiAqL1xuICBzb3VyY2VzOiBSZW1vdGVTa2lsbFNvdXJjZSB8IFJlbW90ZVNraWxsU291cmNlW107XG4gIC8qKlxuICAgKiBGYWlsIGFwcCBzdGFydHVwIHdoZW4gYSBzb3VyY2UgY2FuJ3QgYmUgcmVzb2x2ZWQuIERlZmF1bHRzIHRvIGB0cnVlYC4gQVxuICAgKiBwZXItc291cmNlIGBmYWlsT25FcnJvcmAgd2lucyBvdmVyIHRoaXMuXG4gICAqL1xuICBmYWlsT25FcnJvcj86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBBYnNvbHV0ZSBEYXRhYnJpY2tzIHBhdGggdGhhdCByb290cyB0aGUgZGVzdGluYXRpb24gQXNzaXN0YW50IHNraWxscyB0cmVlLlxuICAgKiBEZWZhdWx0cyB0byB0aGUgT0JPIHVzZXIncyBgL1VzZXJzLzxlbWFpbD4vLmFzc2lzdGFudC9za2lsbHNgLlxuICAgKi9cbiAgZGF0YWJyaWNrc0Jhc2VQYXRoPzogc3RyaW5nO1xuICAvKiogQXV0aC1zY29wZWQgRGF0YWJyaWNrcyBjbGllbnQuIERlZmF1bHRzIHRvIHRoZSBBcHBLaXQgZXhlY3V0aW9uIGNvbnRleHQuICovXG4gIGNsaWVudD86IFdvcmtzcGFjZUNsaWVudExpa2U7XG4gIC8qKiBVc2VyIGVtYWlsIHVzZWQgdG8gZGVyaXZlIHRoZSBkZWZhdWx0IERhdGFicmlja3MgZGVzdGluYXRpb24uICovXG4gIHVzZXJFbWFpbD86IHN0cmluZztcbiAgLyoqIEJ5dGUgY2VpbGluZyBvbiBhIGRpcmVjdC1mZXRjaCBkb3dubG9hZC4gRGVmYXVsdHMgdG8gMTAgTWlCLiAqL1xuICBtYXhEb3dubG9hZEJ5dGVzPzogbnVtYmVyO1xufVxuXG4vKiogV2hhdCB7QGxpbmsgcHJvdmlzaW9uUmVtb3RlU2tpbGxzfSByZXNvbHZlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlzaW9uZWRSZW1vdGVTa2lsbHMge1xuICAvKipcbiAgICogRXh0cmEgTE9DQUwgc2tpbGwgc2NhbiBwYXRocyB0byBoYW5kIE1hc3RyYSAoYSB0ZW1wIGRpciBwZXIgc291cmNlIHRoYXRcbiAgICogY291bGRuJ3QgYmUgd3JpdHRlbiB0byBEYXRhYnJpY2tzKS4gRW1wdHkgd2hlbiBldmVyeXRoaW5nIGxhbmRlZCBpbiB0aGVcbiAgICogRGF0YWJyaWNrcyBBc3Npc3RhbnQgdHJlZSwgd2hpY2ggdGhlIGJ1aWx0LWluIG1vdW50IGFscmVhZHkgc2NhbnMuXG4gICAqL1xuICBsb2NhbFNraWxsUGF0aHM6IHN0cmluZ1tdO1xuICAvKiogQWJzb2x1dGUgRGF0YWJyaWNrcyBkZXN0aW5hdGlvbiBlYWNoIHNvdXJjZSB3YXMgd3JpdHRlbiB0bywgaWYgYW55LiAqL1xuICBkYXRhYnJpY2tzQmFzZVBhdGg/OiBzdHJpbmc7XG4gIC8qKiBOYW1lcyBvZiBldmVyeSBza2lsbCBkaXJlY3RvcnkgdGhhdCB3YXMgcHJvdmlzaW9uZWQuICovXG4gIHNraWxsTmFtZXM6IHN0cmluZ1tdO1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIGhlbHBlcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKiogTm9ybWFsaXplIHRoZSBgcmVtb3RlU2tpbGxzYCBvcHRpb24gaW50byBhIGZsYXQgb3B0aW9ucyBiYWcuICovXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplUmVtb3RlU2tpbGxzT3B0aW9uKFxuICBvcHRpb246IFJlbW90ZVNraWxsc09wdGlvbiB8IHVuZGVmaW5lZCxcbik6IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMgfCB1bmRlZmluZWQge1xuICBpZiAob3B0aW9uID09PSB1bmRlZmluZWQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmICh0eXBlb2Ygb3B0aW9uID09PSBcInN0cmluZ1wiKSByZXR1cm4geyBzb3VyY2VzOiBbb3B0aW9uXSB9O1xuICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb24pKSByZXR1cm4gb3B0aW9uLmxlbmd0aCA+IDAgPyB7IHNvdXJjZXM6IG9wdGlvbiB9IDogdW5kZWZpbmVkO1xuICBpZiAoaXNQcm92aXNpb25PcHRpb25zKG9wdGlvbikpIHtcbiAgICBjb25zdCBzb3VyY2VzID0gQXJyYXkuaXNBcnJheShvcHRpb24uc291cmNlcykgPyBvcHRpb24uc291cmNlcyA6IFtvcHRpb24uc291cmNlc107XG4gICAgcmV0dXJuIHNvdXJjZXMubGVuZ3RoID4gMCA/IHsgLi4ub3B0aW9uLCBzb3VyY2VzIH0gOiB1bmRlZmluZWQ7XG4gIH1cbiAgLy8gQSBsb25lIFJlbW90ZVNraWxsU291cmNlT3B0aW9ucyBvYmplY3QuXG4gIHJldHVybiB7IHNvdXJjZXM6IFtvcHRpb25dIH07XG59XG5cbi8qKiBBIGBzb3VyY2VzYC1iZWFyaW5nIGJhZyBpcyB0aGUgdG9wLWxldmVsIG9wdGlvbnMgc2hhcGUsIG5vdCBhIHNpbmdsZSBzb3VyY2UuICovXG5mdW5jdGlvbiBpc1Byb3Zpc2lvbk9wdGlvbnMoXG4gIHZhbHVlOiBSZW1vdGVTa2lsbFNvdXJjZU9wdGlvbnMgfCBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuKTogdmFsdWUgaXMgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyB7XG4gIHJldHVybiBcInNvdXJjZXNcIiBpbiB2YWx1ZTtcbn1cblxuLyoqIENvZXJjZSBhIHNvdXJjZSBlbnRyeSB0byBpdHMgbm9ybWFsaXplZCB7QGxpbmsgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zfS4gKi9cbmZ1bmN0aW9uIHRvU291cmNlT3B0aW9ucyhzb3VyY2U6IFJlbW90ZVNraWxsU291cmNlKTogUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zIHtcbiAgcmV0dXJuIHR5cGVvZiBzb3VyY2UgPT09IFwic3RyaW5nXCIgPyB7IHNvdXJjZSB9IDogc291cmNlO1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplIGV2ZXJ5IGNvbmZpZ3VyZWQgcmVtb3RlIHNraWxsIHNvdXJjZSBhdCBhcHAgc3RhcnR1cC5cbiAqXG4gKiBXcml0ZXMgZWFjaCByZXNvbHZlZCBgU0tJTEwubWRgIHRyZWUgdG8gdGhlIERhdGFicmlja3MgdXNlciBBc3Npc3RhbnQgc2tpbGxzXG4gKiBmb2xkZXIgd2hlbiBhIHdyaXRhYmxlIHdvcmtzcGFjZSBpcyBhdmFpbGFibGUsIGVsc2UgdG8gYSBsb2NhbCB0ZW1wIGRpclxuICogcmV0dXJuZWQgaW4ge0BsaW5rIFByb3Zpc2lvbmVkUmVtb3RlU2tpbGxzLmxvY2FsU2tpbGxQYXRoc30uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm92aXNpb25SZW1vdGVTa2lsbHMoXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxQcm92aXNpb25lZFJlbW90ZVNraWxscz4ge1xuICBjb25zdCBvcHRpb25zID0gbm9ybWFsaXplUmVtb3RlU2tpbGxzT3B0aW9uKG9wdGlvbik7XG4gIGNvbnN0IGVtcHR5OiBQcm92aXNpb25lZFJlbW90ZVNraWxscyA9IHsgbG9jYWxTa2lsbFBhdGhzOiBbXSwgc2tpbGxOYW1lczogW10gfTtcbiAgaWYgKCFvcHRpb25zKSByZXR1cm4gZW1wdHk7XG5cbiAgY29uc3QgZmFpbERlZmF1bHQgPSBvcHRpb25zLmZhaWxPbkVycm9yICE9PSBmYWxzZTtcbiAgY29uc3QgY2xpZW50ID0gb3B0aW9ucy5jbGllbnQgPz8gYXBwa2l0LnRyeUdldEV4ZWN1dGlvbkNvbnRleHQoKT8uY2xpZW50O1xuICBjb25zdCBkYXRhYnJpY2tzQmFzZVBhdGggPSByZXNvbHZlRGF0YWJyaWNrc0Jhc2VQYXRoKG9wdGlvbnMsIGNsaWVudCk7XG4gIGNvbnN0IGRlc3RpbmF0aW9uID0gZGF0YWJyaWNrc0Jhc2VQYXRoXG4gICAgPyBuZXcgRGF0YWJyaWNrc1dvcmtzcGFjZUZpbGVzeXN0ZW0oeyBjbGllbnQsIGJhc2VQYXRoOiBkYXRhYnJpY2tzQmFzZVBhdGgsIHJlYWRPbmx5OiBmYWxzZSB9KVxuICAgIDogdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGxvY2FsU2tpbGxQYXRoczogc3RyaW5nW10gPSBbXTtcbiAgY29uc3Qgc2tpbGxOYW1lczogc3RyaW5nW10gPSBbXTtcbiAgbGV0IHN0YWdpbmc6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICB0cnkge1xuICAgIGNvbnN0IHNvdXJjZXMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMuc291cmNlcykgPyBvcHRpb25zLnNvdXJjZXMgOiBbb3B0aW9ucy5zb3VyY2VzXTtcbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHNvdXJjZXMpIHtcbiAgICAgIGNvbnN0IHNvdXJjZU9wdGlvbnMgPSB0b1NvdXJjZU9wdGlvbnMoZW50cnkpO1xuICAgICAgY29uc3QgZmFpbE9uRXJyb3IgPSBzb3VyY2VPcHRpb25zLmZhaWxPbkVycm9yID8/IGZhaWxEZWZhdWx0O1xuICAgICAgdHJ5IHtcbiAgICAgICAgc3RhZ2luZyA/Pz0gYXdhaXQgbWtkdGVtcChqb2luKHRtcGRpcigpLCBcIm1hc3RyYS1yZW1vdGUtc2tpbGxzLVwiKSk7XG4gICAgICAgIGNvbnN0IHN0YWdlZERpciA9IGF3YWl0IHN0YWdlU291cmNlKHNvdXJjZU9wdGlvbnMsIHN0YWdpbmcsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBzdGFnZWQgPSBhd2FpdCBjb2xsZWN0U2tpbGxEaXJzKHN0YWdlZERpcik7XG4gICAgICAgIGlmIChzdGFnZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBTS0lMTC5tZCBmb3VuZCBmb3Igc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cImApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZXN0aW5hdGlvbiAmJiBkYXRhYnJpY2tzQmFzZVBhdGgpIHtcbiAgICAgICAgICBhd2FpdCB1cGxvYWRTa2lsbERpcnMoZGVzdGluYXRpb24sIHN0YWdlZCk7XG4gICAgICAgICAgc2tpbGxOYW1lcy5wdXNoKC4uLnN0YWdlZC5tYXAoKGRpcikgPT4gZGlyLm5hbWUpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBsb2NhbERpciA9IGF3YWl0IHBlcnNpc3RMb2NhbGx5KHN0YWdlZCk7XG4gICAgICAgICAgbG9jYWxTa2lsbFBhdGhzLnB1c2gobG9jYWxEaXIpO1xuICAgICAgICAgIHNraWxsTmFtZXMucHVzaCguLi5zdGFnZWQubWFwKChkaXIpID0+IGRpci5uYW1lKSk7XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwic291cmNlOnByb3Zpc2lvbmVkXCIsIHtcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZU9wdGlvbnMuc291cmNlLFxuICAgICAgICAgIGRlc3RpbmF0aW9uOiBkYXRhYnJpY2tzQmFzZVBhdGggPz8gXCJsb2NhbC10ZW1wXCIsXG4gICAgICAgICAgc2tpbGxzOiBzdGFnZWQubWFwKChkaXIpID0+IGRpci5uYW1lKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgaWYgKGZhaWxPbkVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgICAgYGZhaWxlZCB0byBwcm92aXNpb24gcmVtb3RlIHNraWxsIHNvdXJjZSBcIiR7c291cmNlT3B0aW9ucy5zb3VyY2V9XCI6ICR7ZXJyb3IuZXJyb3JNZXNzYWdlKGVycil9YCxcbiAgICAgICAgICAgIHsgY2F1c2U6IGVycm9yLnRvRXJyb3IoZXJyKSB9LFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgbG9nZ2VyLndhcm4oXCJzb3VyY2U6c2tpcHBlZFwiLCB7XG4gICAgICAgICAgc291cmNlOiBzb3VyY2VPcHRpb25zLnNvdXJjZSxcbiAgICAgICAgICBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSBmaW5hbGx5IHtcbiAgICBpZiAoc3RhZ2luZykgYXdhaXQgcm0oc3RhZ2luZywgeyByZWN1cnNpdmU6IHRydWUsIGZvcmNlOiB0cnVlIH0pLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gIH1cblxuICByZXR1cm4geyBsb2NhbFNraWxsUGF0aHMsIGRhdGFicmlja3NCYXNlUGF0aCwgc2tpbGxOYW1lcyB9O1xufVxuXG4vKiogUmVzb2x2ZSB0aGUgRGF0YWJyaWNrcyBBc3Npc3RhbnQgc2tpbGxzIGRlc3RpbmF0aW9uLCBvciBgdW5kZWZpbmVkYCBmb3IgbG9jYWwgdGVtcC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVEYXRhYnJpY2tzQmFzZVBhdGgoXG4gIG9wdGlvbnM6IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMsXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSB8IHVuZGVmaW5lZCxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghY2xpZW50KSByZXR1cm4gdW5kZWZpbmVkO1xuICBpZiAob3B0aW9ucy5kYXRhYnJpY2tzQmFzZVBhdGgpIHJldHVybiBvcHRpb25zLmRhdGFicmlja3NCYXNlUGF0aC50cmltKCkgfHwgdW5kZWZpbmVkO1xuICBjb25zdCBlbWFpbCA9IHN0cmluZy50cmltVG9OdWxsKG9wdGlvbnMudXNlckVtYWlsKTtcbiAgLy8gQSBuYW1lZCB1c2VyIHRhcmdldHMgdGhlaXIgcGVyc29uYWwgQXNzaXN0YW50IHRyZWUgKHRoZSBcInNhdmUgYSBza2lsbFwiXG4gIC8vIHRhcmdldCk7IG90aGVyd2lzZSB0aGUgc2hhcmVkIHdvcmtzcGFjZSBBc3Npc3RhbnQgdHJlZSwgd2hpY2ggdGhlIGJ1aWx0LWluXG4gIC8vIEFzc2lzdGFudC1za2lsbHMgbW91bnQgYWxyZWFkeSBzY2Fucy5cbiAgcmV0dXJuIGVtYWlsID8gdXNlckFzc2lzdGFudFNraWxsc1BhdGgoZW1haWwpIDogQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSDtcbn1cblxuLyoqXG4gKiBTdGFnZSBvbmUgc291cmNlIGludG8gYSBmcmVzaCBkaXIgdW5kZXIgYHN0YWdpbmdgLCBwcmVmZXJyaW5nIHRoZSBvcHRpb25hbFxuICogYHNraWxsc2AgQ0xJIGFuZCBmYWxsaW5nIGJhY2sgdG8gYSBkaXJlY3QgZmV0Y2guXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YWdlU291cmNlKFxuICBzb3VyY2VPcHRpb25zOiBSZW1vdGVTa2lsbFNvdXJjZU9wdGlvbnMsXG4gIHN0YWdpbmc6IHN0cmluZyxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHRhcmdldCA9IGF3YWl0IG1rZHRlbXAoam9pbihzdGFnaW5nLCBcInNyYy1cIikpO1xuICBjb25zdCB2aWFDbGkgPSBhd2FpdCBzdGFnZVZpYVNraWxsc0NsaShzb3VyY2VPcHRpb25zLCB0YXJnZXQpO1xuICBpZiAodmlhQ2xpKSByZXR1cm4gdmlhQ2xpO1xuICByZXR1cm4gc3RhZ2VWaWFGZXRjaChzb3VyY2VPcHRpb25zLCB0YXJnZXQsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIENvcHkgYSBzb3VyY2UgaW50byBgdGFyZ2V0YCB3aXRoIHRoZSBgc2tpbGxzYCBDTEkgd2hlbiBpdCBpcyBpbnN0YWxsZWQuXG4gKiBSZXR1cm5zIHRoZSBkaXIgaG9sZGluZyB0aGUgY29waWVkIGBTS0lMTC5tZGAgdHJlZXMsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlXG4gKiBDTEkgaXMgYWJzZW50IChzbyB0aGUgY2FsbGVyIGNhbiBmYWxsIGJhY2sgdG8gYSBmZXRjaCkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YWdlVmlhU2tpbGxzQ2xpKFxuICBzb3VyY2VPcHRpb25zOiBSZW1vdGVTa2lsbFNvdXJjZU9wdGlvbnMsXG4gIHRhcmdldDogc3RyaW5nLFxuKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgY2xpID0gYXdhaXQgcmVzb2x2ZVNraWxsc0NsaSgpO1xuICBpZiAoIWNsaSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBjb25zdCBhcmdzID0gW1xuICAgIC4uLmNsaS5hcmdzLFxuICAgIFwiYWRkXCIsXG4gICAgc291cmNlT3B0aW9ucy5zb3VyY2UsXG4gICAgXCItLWFnZW50XCIsXG4gICAgU0tJTExTX0NMSV9BR0VOVCxcbiAgICBcIi0tY29weVwiLFxuICAgIFwiLXlcIixcbiAgXTtcbiAgZm9yIChjb25zdCBza2lsbCBvZiBzdHJpbmcucGFyc2VMaXN0KHNvdXJjZU9wdGlvbnMuc2tpbGxzKSkge1xuICAgIGFyZ3MucHVzaChcIi0tc2tpbGxcIiwgc2tpbGwpO1xuICB9XG4gIGlmIChzdHJpbmcucGFyc2VMaXN0KHNvdXJjZU9wdGlvbnMuc2tpbGxzKS5sZW5ndGggPT09IDApIGFyZ3MucHVzaChcIi0tc2tpbGxcIiwgXCIqXCIpO1xuXG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNwYXduKGNsaS5jb21tYW5kLCBhcmdzLCB7XG4gICAgY3dkOiB0YXJnZXQsXG4gICAgc3Rkb3V0OiBcImNhcHR1cmVcIixcbiAgICBzdGRlcnI6IFwiY2FwdHVyZVwiLFxuICAgIGNoZWNrOiBmYWxzZSxcbiAgfSk7XG4gIGlmIChyZXN1bHQuZXhpdENvZGUgIT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgc2tpbGxzIENMSSBmYWlsZWQgKGV4aXQgJHtyZXN1bHQuZXhpdENvZGV9KTogJHtyZXN1bHQuc3RkZXJyIHx8IHJlc3VsdC5zdGRvdXR9YCxcbiAgICApO1xuICB9XG4gIHJldHVybiBqb2luKHRhcmdldCwgLi4uU0tJTExTX0NMSV9MQVlPVVQpO1xufVxuXG4vKipcbiAqIExvY2F0ZSB0aGUgb3B0aW9uYWwgYHNraWxsc2AgQ0xJIGJpbiwgcmVzb2x2ZWQgZnJvbSBUSElTIHBhY2thZ2UncyBtb2R1bGVcbiAqIGdyYXBoLiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlIHBlZXIgZGVwIGlzbid0IGluc3RhbGxlZCwgc28gdGhlIGNhbGxlclxuICogZmFsbHMgYmFjayB0byBhIGRpcmVjdCBmZXRjaC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZVNraWxsc0NsaSgpOiBQcm9taXNlPHsgY29tbWFuZDogc3RyaW5nOyBhcmdzOiBzdHJpbmdbXSB9IHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoaW1wb3J0Lm1ldGEudXJsKTtcbiAgICBjb25zdCBwa2dQYXRoID0gcmVxdWlyZS5yZXNvbHZlKFwic2tpbGxzL3BhY2thZ2UuanNvblwiKTtcbiAgICBjb25zdCBiaW4gPSBqb2luKHBrZ1BhdGgsIFwiLi5cIiwgXCJiaW5cIiwgXCJjbGkubWpzXCIpO1xuICAgIGlmIChhd2FpdCBwYXRoRXhpc3RzKGJpbikpIHJldHVybiB7IGNvbW1hbmQ6IHByb2Nlc3MuZXhlY1BhdGgsIGFyZ3M6IFtiaW5dIH07XG4gIH0gY2F0Y2gge1xuICAgIC8vIHBlZXIgZGVwIGFic2VudCBvciB1bnJlc29sdmFibGUgLSBmZXRjaCBmYWxsYmFjayBoYW5kbGVzIGl0XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBGZXRjaCBhIHNvdXJjZSBVUkwgYW5kIHdyaXRlIHRoZSBkb3dubG9hZGVkIGBTS0lMTC5tZGAgdW5kZXIgYHRhcmdldGAuXG4gKiBVc2VkIHdoZW4gdGhlIGBza2lsbHNgIENMSSBpc24ndCBpbnN0YWxsZWQ7IHN1cHBvcnRzIGEgZGlyZWN0IGBTS0lMTC5tZGAgVVJMLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFnZVZpYUZldGNoKFxuICBzb3VyY2VPcHRpb25zOiBSZW1vdGVTa2lsbFNvdXJjZU9wdGlvbnMsXG4gIHRhcmdldDogc3RyaW5nLFxuICBvcHRpb25zOiBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgdXJsID0gbmV0LnVybEJ1aWxkZXIoc291cmNlT3B0aW9ucy5zb3VyY2UpO1xuICBpZiAoIXVybCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBzb3VyY2UgXCIke3NvdXJjZU9wdGlvbnMuc291cmNlfVwiIGlzIG5vdCBhIFVSTCBhbmQgdGhlIG9wdGlvbmFsIFwic2tpbGxzXCIgcGFja2FnZSBpcyBub3QgaW5zdGFsbGVkYCxcbiAgICApO1xuICB9XG4gIGNvbnN0IG1heEJ5dGVzID1cbiAgICBzb3VyY2VPcHRpb25zLm1heERvd25sb2FkQnl0ZXMgPz8gb3B0aW9ucy5tYXhEb3dubG9hZEJ5dGVzID8/IERFRkFVTFRfTUFYX0RPV05MT0FEX0JZVEVTO1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybC50b1N0cmluZygpKTtcbiAgaWYgKCFyZXNwb25zZS5vaykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBkb3dubG9hZCBmYWlsZWQ6ICR7cmVzcG9uc2Uuc3RhdHVzfSAke3Jlc3BvbnNlLnN0YXR1c1RleHR9ICgke3VybC50b1N0cmluZygpfSlgLFxuICAgICk7XG4gIH1cbiAgY29uc3QgYnVmZmVyID0gQnVmZmVyLmZyb20oYXdhaXQgcmVzcG9uc2UuYXJyYXlCdWZmZXIoKSk7XG4gIGlmIChidWZmZXIuYnl0ZUxlbmd0aCA+IG1heEJ5dGVzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBkb3dubG9hZCBleGNlZWRzICR7bWF4Qnl0ZXN9IGJ5dGVzICgke3VybC50b1N0cmluZygpfSlgKTtcbiAgfVxuICBjb25zdCBuYW1lID0gc3RyaW5nLnRvU2x1ZyhkZXJpdmVTa2lsbE5hbWUodXJsLnRvU3RyaW5nKCkpKSB8fCBcInJlbW90ZS1za2lsbFwiO1xuICBjb25zdCBza2lsbERpciA9IGpvaW4odGFyZ2V0LCBuYW1lKTtcbiAgYXdhaXQgbWtkaXIoc2tpbGxEaXIsIHsgcmVjdXJzaXZlOiB0cnVlIH0pO1xuICBhd2FpdCB3cml0ZUZpbGUoam9pbihza2lsbERpciwgXCJTS0lMTC5tZFwiKSwgYnVmZmVyKTtcbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqIERlcml2ZSBhIHNraWxsIGRpcmVjdG9yeSBuYW1lIGZyb20gYSBkb3dubG9hZCBVUkwncyBsYXN0IHBhdGggc2VnbWVudC4gKi9cbmZ1bmN0aW9uIGRlcml2ZVNraWxsTmFtZSh1cmxTdHJpbmc6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHVybCA9IG5ldC51cmxCdWlsZGVyKHVybFN0cmluZyk7XG4gIGNvbnN0IGxhc3QgPSB1cmw/LnBhdGhuYW1lLnNwbGl0KFwiL1wiKS5maWx0ZXIoQm9vbGVhbikucG9wKCkgPz8gXCJcIjtcbiAgcmV0dXJuIGxhc3QucmVwbGFjZSgvXFwuKG1kfHppcHx0YXJ8dGd6fGd6KSQvaSwgXCJcIik7XG59XG5cbi8qKiBBIHNraWxsIGRpcmVjdG9yeSAoaG9sZGluZyBhIGBTS0lMTC5tZGApIHN0YWdlZCBvbiBsb2NhbCBkaXNrLiAqL1xuaW50ZXJmYWNlIFN0YWdlZFNraWxsRGlyIHtcbiAgbmFtZTogc3RyaW5nO1xuICBhYnNvbHV0ZVBhdGg6IHN0cmluZztcbn1cblxuLyoqXG4gKiBDb2xsZWN0IGV2ZXJ5IHNraWxsIGRpcmVjdG9yeSB1bmRlciBgcm9vdGA6IGEgYHJvb3QvU0tJTEwubWRgIChyb290IElTIHRoZVxuICogc2tpbGwpIG9yIGVhY2ggaW1tZWRpYXRlIGNoaWxkIGRpciB0aGF0IGNvbnRhaW5zIGEgYFNLSUxMLm1kYC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gY29sbGVjdFNraWxsRGlycyhyb290OiBzdHJpbmcpOiBQcm9taXNlPFN0YWdlZFNraWxsRGlyW10+IHtcbiAgaWYgKCEoYXdhaXQgcGF0aEV4aXN0cyhyb290KSkpIHJldHVybiBbXTtcbiAgaWYgKGF3YWl0IHBhdGhFeGlzdHMoam9pbihyb290LCBcIlNLSUxMLm1kXCIpKSkge1xuICAgIGNvbnN0IG5hbWUgPSBwb3NpeC5iYXNlbmFtZShyb290LnNwbGl0KC9bXFxcXC9dLykuam9pbihcIi9cIikpO1xuICAgIHJldHVybiBbeyBuYW1lLCBhYnNvbHV0ZVBhdGg6IHJvb3QgfV07XG4gIH1cbiAgY29uc3QgZGlyczogU3RhZ2VkU2tpbGxEaXJbXSA9IFtdO1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGF3YWl0IHJlYWRkaXIocm9vdCwgeyB3aXRoRmlsZVR5cGVzOiB0cnVlIH0pKSB7XG4gICAgaWYgKCFlbnRyeS5pc0RpcmVjdG9yeSgpKSBjb250aW51ZTtcbiAgICBjb25zdCBkaXIgPSBqb2luKHJvb3QsIGVudHJ5Lm5hbWUpO1xuICAgIGlmIChhd2FpdCBwYXRoRXhpc3RzKGpvaW4oZGlyLCBcIlNLSUxMLm1kXCIpKSkge1xuICAgICAgZGlycy5wdXNoKHsgbmFtZTogZW50cnkubmFtZSwgYWJzb2x1dGVQYXRoOiBkaXIgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBkaXJzO1xufVxuXG4vKiogVXBsb2FkIGVhY2ggc3RhZ2VkIHNraWxsIGRpcmVjdG9yeSBpbnRvIHRoZSBEYXRhYnJpY2tzIGRlc3RpbmF0aW9uIHRyZWUuICovXG5hc3luYyBmdW5jdGlvbiB1cGxvYWRTa2lsbERpcnMoXG4gIGRlc3RpbmF0aW9uOiBEYXRhYnJpY2tzV29ya3NwYWNlRmlsZXN5c3RlbSxcbiAgZGlyczogU3RhZ2VkU2tpbGxEaXJbXSxcbik6IFByb21pc2U8dm9pZD4ge1xuICBhd2FpdCBkZXN0aW5hdGlvbi5pbml0Py4oKTtcbiAgZm9yIChjb25zdCBkaXIgb2YgZGlycykge1xuICAgIGZvciAoY29uc3QgcmVsYXRpdmUgb2YgZmluZEZpbGVzKFwiKiovKlwiLCB7IGN3ZDogZGlyLmFic29sdXRlUGF0aCwgbm9kaXI6IHRydWUgfSkpIHtcbiAgICAgIGNvbnN0IGJ1ZmZlciA9IGF3YWl0IHJlYWRGaWxlKGpvaW4oZGlyLmFic29sdXRlUGF0aCwgcmVsYXRpdmUpKTtcbiAgICAgIGNvbnN0IHJlbW90ZVBhdGggPSBwb3NpeC5qb2luKFwiL1wiLCBkaXIubmFtZSwgcmVsYXRpdmUuc3BsaXQoL1tcXFxcL10vKS5qb2luKFwiL1wiKSk7XG4gICAgICBhd2FpdCBkZXN0aW5hdGlvbi53cml0ZUZpbGUocmVtb3RlUGF0aCwgYnVmZmVyLCB7IG92ZXJ3cml0ZTogdHJ1ZSB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqIENvcHkgc3RhZ2VkIHNraWxsIGRpcnMgaW50byBhIHBlcnNpc3RlbnQgbG9jYWwgdGVtcCBkaXI7IHJldHVybiBpdHMgcGF0aC4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBlcnNpc3RMb2NhbGx5KGRpcnM6IFN0YWdlZFNraWxsRGlyW10pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCBiYXNlID0gYXdhaXQgbWtkdGVtcChqb2luKHRtcGRpcigpLCBcIm1hc3RyYS1sb2NhbC1za2lsbHMtXCIpKTtcbiAgZm9yIChjb25zdCBkaXIgb2YgZGlycykge1xuICAgIGF3YWl0IGNwKGRpci5hYnNvbHV0ZVBhdGgsIGpvaW4oYmFzZSwgZGlyLm5hbWUpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgfVxuICByZXR1cm4gYmFzZTtcbn1cblxuLyoqIEJlc3QtZWZmb3J0IGV4aXN0ZW5jZSBjaGVjay4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBhdGhFeGlzdHMocGF0aDogc3RyaW5nKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIHRyeSB7XG4gICAgYXdhaXQgc3RhdChwYXRoKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iXX0=
425
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVtb3RlLXNraWxscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZW1vdGUtc2tpbGxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNDRztBQUVILE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDNUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUUzQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDdkMsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDN0QsT0FBTyxFQUFFLE9BQU8sRUFBd0IsTUFBTSxlQUFlLENBQUM7QUFDOUQsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUlyRixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLHNCQUFzQixDQUFDLENBQUM7QUFFbEQsaUZBQWlGO0FBQ2pGLE1BQU0sNEJBQTRCLEdBQUcsOEJBQThCLENBQUM7QUFFcEUsaUVBQWlFO0FBQ2pFLFNBQVMsdUJBQXVCLENBQUMsU0FBaUI7SUFDaEQsT0FBTyxVQUFVLFNBQVMsQ0FBQyxJQUFJLEVBQUUsb0JBQW9CLENBQUM7QUFDeEQsQ0FBQztBQUVELDJFQUEyRTtBQUMzRSxNQUFNLGdCQUFnQixHQUFHLFFBQVEsQ0FBQztBQUVsQywrRUFBK0U7QUFDL0UsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLFNBQVMsRUFBRSxRQUFRLENBQVUsQ0FBQztBQUV6RCw4RUFBOEU7QUFDOUUsTUFBTSwwQkFBMEIsR0FBRyxFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUVwRCw4RUFBOEU7QUFDOUUsTUFBTSxnQkFBZ0IsR0FBRyxxQkFBcUIsQ0FBQztBQUUvQyw0RUFBNEU7QUFFNUU7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsU0FBUyxDQUFDO0FBS3hDOzs7O0dBSUc7QUFDSCxNQUFNLFlBQVksR0FBRyxvQ0FBb0MsQ0FBQztBQUUxRCx5RUFBeUU7QUFDekUsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDO0FBRTNCLGlGQUFpRjtBQUNqRixNQUFNLG1CQUFtQixHQUFHLENBQUMsQ0FBQztBQXVGOUIsNkVBQTZFO0FBRTdFLG1FQUFtRTtBQUNuRSxNQUFNLFVBQVUsMkJBQTJCLENBQ3pDLE1BQXNDO0lBRXRDLElBQUksTUFBTSxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUMzQyxNQUFNLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDNUQsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUUsTUFBNEIsQ0FBQyxDQUFDO0lBQ2hGLHdEQUF3RDtJQUN4RCxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNuRCxPQUFPLEVBQUUsR0FBRyxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUM7QUFDN0IsQ0FBQztBQUVELG1GQUFtRjtBQUNuRixTQUFTLGtCQUFrQixDQUFDLEtBQWM7SUFDeEMsT0FBTyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLFNBQVMsSUFBSSxLQUFLLENBQUM7QUFDdEQsQ0FBQztBQUVELCtFQUErRTtBQUMvRSxTQUFTLFlBQVksQ0FDbkIsS0FBdUQ7SUFFdkQsT0FBTyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDckQsQ0FBQztBQUVELHlHQUF5RztBQUN6RyxTQUFTLGVBQWUsQ0FBQyxNQUF5QjtJQUNoRCxJQUFJLE9BQU8sTUFBTSxLQUFLLFFBQVE7UUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLENBQUM7SUFDbEQsSUFBSSxNQUFNLFlBQVksR0FBRztRQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUM7SUFDaEUsSUFBSSxRQUFRLElBQUksTUFBTTtRQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sRUFBRSxNQUFNLEVBQUUsY0FBYyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO0lBQ3BGLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsU0FBUyxjQUFjLENBQUMsTUFBbUI7SUFDekMsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRO1FBQUUsT0FBTyxNQUFNLENBQUM7SUFDOUMsT0FBTyxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7QUFDaEUsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSxTQUFTLGVBQWUsQ0FBQyxNQUFjO0lBQ3JDLE9BQU8sTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxLQUFLLGNBQWMsQ0FBQztBQUN4RCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxxQkFBcUIsQ0FDekMsTUFBc0M7SUFFdEMsTUFBTSxPQUFPLEdBQUcsMkJBQTJCLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDcEQsTUFBTSxLQUFLLEdBQTRCLEVBQUUsZUFBZSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDL0UsSUFBSSxDQUFDLE9BQU87UUFBRSxPQUFPLEtBQUssQ0FBQztJQUUzQixNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsV0FBVyxLQUFLLEtBQUssQ0FBQztJQUNsRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLE1BQU0sQ0FBQztJQUN6RSxNQUFNLGtCQUFrQixHQUFHLHlCQUF5QixDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztJQUN0RSxNQUFNLFdBQVcsR0FBRyxrQkFBa0I7UUFDcEMsQ0FBQyxDQUFDLElBQUksb0JBQW9CLENBQUM7WUFDdkIsTUFBTSxFQUFFLE1BQXlCO1lBQ2pDLElBQUksRUFBRSxrQkFBa0I7WUFDeEIsUUFBUSxFQUFFLEtBQUs7WUFDZixVQUFVLEVBQUUsSUFBSTtTQUNqQixDQUFDO1FBQ0osQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUVkLE1BQU0sZUFBZSxHQUFhLEVBQUUsQ0FBQztJQUNyQyxNQUFNLFVBQVUsR0FBYSxFQUFFLENBQUM7SUFDaEMsSUFBSSxPQUFvQyxDQUFDO0lBRXpDLElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyRixLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQzVCLE1BQU0sYUFBYSxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUM3QyxNQUFNLFdBQVcsR0FBRyxhQUFhLENBQUMsV0FBVyxJQUFJLFdBQVcsQ0FBQztZQUM3RCxJQUFJLENBQUM7Z0JBQ0gsT0FBTyxLQUFLLE1BQU0sa0JBQWtCLENBQUMsc0JBQXNCLENBQUMsQ0FBQztnQkFDN0QsTUFBTSxTQUFTLEdBQUcsTUFBTSxXQUFXLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQzFFLE1BQU0sTUFBTSxHQUFHLE1BQU0sZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUM7Z0JBQ2pELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDeEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7Z0JBQzVFLENBQUM7Z0JBQ0QsSUFBSSxXQUFXLElBQUksa0JBQWtCLEVBQUUsQ0FBQztvQkFDdEMsTUFBTSxhQUFhLENBQUMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxDQUFDO29CQUN6QyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLFFBQVEsR0FBRyxNQUFNLGNBQWMsQ0FBQyxhQUFhLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO29CQUNwRSxlQUFlLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUMvQixVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELENBQUM7Z0JBQ0QsTUFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsRUFBRTtvQkFDakMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxNQUFNO29CQUM1QixXQUFXLEVBQUUsa0JBQWtCLElBQUksWUFBWTtvQkFDL0MsTUFBTSxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7aUJBQ3RDLENBQUMsQ0FBQztZQUNMLENBQUM7WUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO2dCQUNiLElBQUksV0FBVyxFQUFFLENBQUM7b0JBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQ2IsNENBQTRDLGFBQWEsQ0FBQyxNQUFNLE1BQU0sS0FBSyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUMvRixFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQzlCLENBQUM7Z0JBQ0osQ0FBQztnQkFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFO29CQUM1QixNQUFNLEVBQUUsYUFBYSxDQUFDLE1BQU07b0JBQzVCLEtBQUssRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQztpQkFDL0IsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO1lBQVMsQ0FBQztRQUNULElBQUksT0FBTyxFQUFFLENBQUM7WUFDWixNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEYsQ0FBQztJQUNILENBQUM7SUFFRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGtCQUFrQixFQUFFLFVBQVUsRUFBRSxDQUFDO0FBQzdELENBQUM7QUFFRCwwRkFBMEY7QUFDMUYsU0FBUyx5QkFBeUIsQ0FDaEMsT0FBcUMsRUFDckMsTUFBdUM7SUFFdkMsSUFBSSxDQUFDLE1BQU07UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM5QixJQUFJLE9BQU8sQ0FBQyxrQkFBa0I7UUFBRSxPQUFPLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxTQUFTLENBQUM7SUFDdEYsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbkQseUVBQXlFO0lBQ3pFLDZFQUE2RTtJQUM3RSx3Q0FBd0M7SUFDeEMsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyw0QkFBNEIsQ0FBQztBQUMvRSxDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsS0FBSyxVQUFVLFdBQVcsQ0FDeEIsYUFBK0IsRUFDL0IsV0FBbUIsRUFDbkIsT0FBcUM7SUFFckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDckQsTUFBTSxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDekMseUVBQXlFO0lBQ3pFLElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUM7UUFBRSxPQUFPLFlBQVksQ0FBQyxhQUFhLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQy9GLE1BQU0sTUFBTSxHQUFHLE1BQU0saUJBQWlCLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzlELElBQUksTUFBTTtRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQzFCLE9BQU8sYUFBYSxDQUFDLGFBQWEsRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDdkQsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxLQUFLLFVBQVUsWUFBWSxDQUN6QixhQUErQixFQUMvQixNQUFjLEVBQ2QsT0FBcUM7SUFFckMsTUFBTSxRQUFRLEdBQUcsZUFBZSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUMsQ0FBQztJQUN6RCxNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBSSxXQUFXLENBQUM7SUFDaEUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDekIsQ0FBQyxNQUFNLFFBQVEsQ0FBQyxhQUFhLENBQUMsR0FBRyxFQUFFLGVBQWUsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUNoRixTQUFTLENBQ3FCLENBQUM7SUFFakMsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUMvRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUMvRSxNQUFNLENBQUMsSUFBSSxHQUFHLENBQUM7UUFDYixDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7UUFDbEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLEtBQUssY0FBYyxJQUFJLGFBQWEsQ0FBQyxZQUFZLEtBQUssSUFBSSxDQUM3RSxDQUFDO0lBQ0YsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxLQUFLLENBQUMseUJBQXlCLFlBQVksSUFBSSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUMvQyxDQUFDLEtBQUssQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ2pDLEdBQUcsRUFBRSxhQUFhLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSxRQUFRLElBQUksSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3hFLElBQUksRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDN0MsQ0FBQyxDQUFDLENBQ0osQ0FBQztJQUNGLE1BQU0sYUFBYSxDQUFDLEtBQUssRUFBRSxtQkFBbUIsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEVBQUU7UUFDN0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNoRCxNQUFNLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDckQsTUFBTSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDLENBQUMsQ0FBQztJQUVILE1BQU0sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0lBQ3RGLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxnRUFBZ0U7QUFDaEUsU0FBUyxhQUFhLENBQUMsR0FBVyxFQUFFLElBQVk7SUFDOUMsT0FBTyxxQ0FBcUMsWUFBWSxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztBQUM1RSxDQUFDO0FBRUQsNERBQTREO0FBQzVELEtBQUssVUFBVSxhQUFhLENBQzFCLEtBQW1CLEVBQ25CLEtBQWEsRUFDYixNQUFrQztJQUVsQyxJQUFJLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDZixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLEtBQUssSUFBSSxFQUFFO1FBQy9FLE9BQU8sTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM3QixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUUsQ0FBQyxDQUFDO1FBQ2pDLENBQUM7SUFDSCxDQUFDLENBQUMsQ0FBQztJQUNILE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUM3QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILEtBQUssVUFBVSxpQkFBaUIsQ0FDOUIsYUFBK0IsRUFDL0IsTUFBYztJQUVkLE1BQU0sR0FBRyxHQUFHLE1BQU0sZ0JBQWdCLEVBQUUsQ0FBQztJQUNyQyxJQUFJLENBQUMsR0FBRztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBRTNCLE1BQU0sSUFBSSxHQUFHO1FBQ1gsR0FBRyxHQUFHLENBQUMsSUFBSTtRQUNYLEtBQUs7UUFDTCxhQUFhLENBQUMsTUFBTTtRQUNwQixTQUFTO1FBQ1QsZ0JBQWdCO1FBQ2hCLFFBQVE7UUFDUixJQUFJO0tBQ0wsQ0FBQztJQUNGLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUMzRCxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRW5GLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRTtRQUNqRCxHQUFHLEVBQUUsTUFBTTtRQUNYLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLE1BQU0sRUFBRSxTQUFTO1FBQ2pCLEtBQUssRUFBRSxLQUFLO0tBQ2IsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxNQUFNLENBQUMsUUFBUSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzFCLE1BQU0sSUFBSSxLQUFLLENBQ2IsMkJBQTJCLE1BQU0sQ0FBQyxRQUFRLE1BQU0sTUFBTSxDQUFDLE1BQU0sSUFBSSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQ2pGLENBQUM7SUFDSixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsaUJBQWlCLENBQUMsQ0FBQztBQUM1QyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILEtBQUssVUFBVSxnQkFBZ0I7SUFDN0IsSUFBSSxDQUFDO1FBQ0gsTUFBTSxPQUFPLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDL0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ3ZELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztRQUNsRCxJQUFJLE1BQU0sVUFBVSxDQUFDLEdBQUcsQ0FBQztZQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO0lBQy9FLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCw4REFBOEQ7SUFDaEUsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxLQUFLLFVBQVUsYUFBYSxDQUMxQixhQUErQixFQUMvQixNQUFjLEVBQ2QsT0FBcUM7SUFFckMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDakQsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ1QsTUFBTSxJQUFJLEtBQUssQ0FDYixXQUFXLGFBQWEsQ0FBQyxNQUFNLG1FQUFtRSxDQUNuRyxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsRUFBRSxlQUFlLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDdkYsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsSUFBSSxjQUFjLENBQUM7SUFDOUUsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwQyxNQUFNLEtBQUssQ0FBQyxRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUMzQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLFVBQVUsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3BELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCxvRkFBb0Y7QUFDcEYsU0FBUyxlQUFlLENBQ3RCLGFBQStCLEVBQy9CLE9BQXFDO0lBRXJDLE9BQU8sYUFBYSxDQUFDLGdCQUFnQixJQUFJLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSwwQkFBMEIsQ0FBQztBQUNsRyxDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLEtBQUssVUFBVSxRQUFRLENBQUMsR0FBVyxFQUFFLFFBQWdCO0lBQ25ELE1BQU0sUUFBUSxHQUFHLE1BQU0sS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ2xDLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsUUFBUSxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDekYsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztJQUN6RCxJQUFJLE1BQU0sQ0FBQyxVQUFVLEdBQUcsUUFBUSxFQUFFLENBQUM7UUFDakMsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQkFBb0IsUUFBUSxXQUFXLEdBQUcsR0FBRyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCw2RUFBNkU7QUFDN0UsU0FBUyxlQUFlLENBQUMsU0FBaUI7SUFDeEMsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0QyxNQUFNLElBQUksR0FBRyxHQUFHLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ2xFLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNyRCxDQUFDO0FBUUQ7OztHQUdHO0FBQ0gsS0FBSyxVQUFVLGdCQUFnQixDQUFDLElBQVk7SUFDMUMsSUFBSSxDQUFDLENBQUMsTUFBTSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN6QyxJQUFJLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzdDLE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxPQUFPLENBQUMsRUFBRSxJQUFJLEVBQUUsWUFBWSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFxQixFQUFFLENBQUM7SUFDbEMsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQ2pFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxFQUFFO1lBQUUsU0FBUztRQUNuQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuQyxJQUFJLE1BQU0sVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzVDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksRUFBRSxZQUFZLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNyRCxDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxLQUFLLFVBQVUsYUFBYSxDQUFDLFdBQXVCLEVBQUUsSUFBc0I7SUFDMUUsTUFBTSxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDekIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixLQUFLLE1BQU0sUUFBUSxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxZQUFZLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztZQUN0RixNQUFNLE1BQU0sR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQzFFLE1BQU0sV0FBVyxDQUFDLFNBQVMsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxLQUFLLFVBQVUsY0FBYyxDQUFDLE1BQWMsRUFBRSxJQUFzQjtJQUNsRSxNQUFNLE1BQU0sR0FBRyxNQUFNLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxnQkFBZ0IsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNoRyxhQUFhLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUM3QixDQUFDO0lBQ0YsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDO0FBQ3JCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsS0FBSyxVQUFVLGtCQUFrQixDQUFDLE1BQWM7SUFDOUMsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMxQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNyQixPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQsbUNBQW1DO0FBQ25DLEtBQUssVUFBVSxVQUFVLENBQUMsSUFBWTtJQUNwQyxJQUFJLENBQUM7UUFDSCxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNqQixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBTdGFydHVwIHByb3Zpc2lvbmluZyBvZiByZW1vdGUgQWdlbnQtU2tpbGwgc291cmNlcyBmb3IgYSBNYXN0cmEgd29ya3NwYWNlLlxuICpcbiAqIEEge0BsaW5rIFJlbW90ZVNraWxsU291cmNlfSBuYW1lcyBXSEVSRSBhIGBTS0lMTC5tZGAgdHJlZSBjb21lcyBmcm9tIC0gdGhlXG4gKiB7QGxpbmsgQUlUT09MU19TT1VSQ0V9IGNvbnN0YW50LCBhIEdpdEh1YiBgb3duZXIvcmVwb2AsIGFueSBnaXQgLyBHaXRMYWIgVVJMLFxuICogb3IgYSBkaXJlY3QgZG93bmxvYWQgVVJMIC0gYW5kIG9wdGlvbmFsIHBlci1zb3VyY2UgcG9saWN5LlxuICoge0BsaW5rIHByb3Zpc2lvblJlbW90ZVNraWxsc30gbWF0ZXJpYWxpemVzIGV2ZXJ5IHNvdXJjZSBpbnRvIGEgbG9jYWxcbiAqIGBTS0lMTC5tZGAgdHJlZSBhdCBhcHAgYm9vdCBhbmQgcmV0dXJucyB0aGUgZGlyZWN0b3JpZXMgdG8gaGFuZCBNYXN0cmEgYXNcbiAqIGV4dHJhIHNraWxsIHNjYW4gcGF0aHMuXG4gKlxuICogUmVzb2x1dGlvbiBwZXIgc291cmNlLCBpbiBvcmRlcjpcbiAqXG4gKiAxLiB0aGUge0BsaW5rIEFJVE9PTFNfU09VUkNFfSBjb25zdGFudCAoYFwiYWl0b29sc1wiYCk6IERhdGFicmlja3MnIG93biBza2lsbFxuICogICAgc2V0LCByZWFkIHN0cmFpZ2h0IGZyb20gdGhlIHB1YmxpYyByZXBvIHRoZSBgZGF0YWJyaWNrcyBhaXRvb2xzYCBDTElcbiAqICAgIHNvdXJjZXMgZnJvbS4gTm8gQ0xJLCBubyBEYXRhYnJpY2tzIGF1dGggLSB3aGljaCBpcyB3aGF0IG1ha2VzIGl0IHVzYWJsZVxuICogICAgaW5zaWRlIGEgRGF0YWJyaWNrcyBBcHAgY29udGFpbmVyLCB3aGVyZSB0aGUgQ0xJIGlzIG5vdCBpbnN0YWxsZWQ7XG4gKiAyLiB0aGUgT1BUSU9OQUwgYHNraWxsc2AgbnBtIENMSSAocGVlciBkZXApOiBpZiBpbnN0YWxsZWQsIGVhY2ggc291cmNlIGlzXG4gKiAgICBjb3BpZWQgaW50byBhIHN0YWdpbmcgZGlyIHdpdGggYHNraWxscyBhZGQgPHNvdXJjZT4gLS1hZ2VudCA8ZGlyPiAtLWNvcHlgLFxuICogICAgd2hpY2ggdW5kZXJzdGFuZHMgZXZlcnkgc291cmNlIGZvcm1hdCB0aGUgZWNvc3lzdGVtIGRvZXMgKEdpdEh1YlxuICogICAgc2hvcnRoYW5kLCBnaXQgVVJMcywgYXJjaGl2ZS9kb3dubG9hZCBVUkxzKTtcbiAqIDMuIG90aGVyd2lzZSBhIHBsYWluIHtAbGluayBmZXRjaH0gb2YgdGhlIHNvdXJjZSBVUkwgKGJ1aWx0IHdpdGhcbiAqICAgIHtAbGluayBuZXQudXJsQnVpbGRlcn0pLCB3cml0aW5nIHRoZSBkb3dubG9hZGVkIGBTS0lMTC5tZGAgdG8gYSBzdGFnaW5nXG4gKiAgICBkaXIuXG4gKlxuICogQSBzb3VyY2UgdGhhdCByZXNvbHZlcyB0aHJvdWdoIG5laXRoZXIgcGF0aCBmYWlscyBhcHAgc3RhcnR1cCwgdW5sZXNzIHRoZVxuICogc291cmNlIChvciB0aGUgdG9wLWxldmVsIGNhbGwpIHNldHMgYGZhaWxPbkVycm9yOiBmYWxzZWAsIGluIHdoaWNoIGNhc2UgaXQgaXNcbiAqIGxvZ2dlZCBhbmQgc2tpcHBlZCBzbyBvbmUgYmFkIHNvdXJjZSBuZXZlciB0YWtlcyB0aGUgYXBwIGRvd24uXG4gKlxuICogVGhlIGRlZmF1bHQgZGVzdGluYXRpb24gaXMgdGhlIERhdGFicmlja3Mgd29ya3NwYWNlIEFzc2lzdGFudCBza2lsbHMgdHJlZVxuICogKGAvV29ya3NwYWNlLy5hc3Npc3RhbnQvc2tpbGxzYCwgdGhlIHNhbWUgdHJlZSBhIFwic2F2ZSB0aGlzIGFzIGEgc2tpbGxcIlxuICogYWN0aW9uIHdyaXRlcyB0byksIHNvIHByb3Zpc2lvbmVkIHNraWxscyBwZXJzaXN0IGFjcm9zcyByZXN0YXJ0cyBhbmQgYXJlXG4gKiBkaXNjb3ZlcmVkIGJ5IHRoZSBidWlsdC1pbiBBc3Npc3RhbnQtc2tpbGxzIG1vdW50LiBQYXNzIGB1c2VyRW1haWxgIChvciBhblxuICogZXhwbGljaXQgYGRhdGFicmlja3NCYXNlUGF0aGApIHRvIHRhcmdldCBgL1VzZXJzLzxlbWFpbD4vLmFzc2lzdGFudC9za2lsbHNgXG4gKiBpbnN0ZWFkLiBXaGVuIG5vIERhdGFicmlja3MgY2xpZW50IGlzIHJlc29sdmFibGUgYXQgc3RhcnR1cCwgdGhlIHRyZWUgaXNcbiAqIHdyaXR0ZW4gdW5kZXIge0BsaW5rIGxvY2FsRlMudG1wRlN9IGFuZCByZXR1cm5lZCBhcyBhbiBleHRyYSBsb2NhbCBza2lsbCBwYXRoXG4gKiBmb3IgdGhlIGN1cnJlbnQgcHJvY2Vzcy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbWtkaXIsIHJlYWRkaXIsIHJlYWRGaWxlLCBybSwgc3RhdCwgd3JpdGVGaWxlIH0gZnJvbSBcIm5vZGU6ZnMvcHJvbWlzZXNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGpvaW4sIHBvc2l4IH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VDbGllbnQgfSBmcm9tIFwiQGRhdGFicmlja3Mvc2RrLWV4cGVyaW1lbnRhbFwiO1xuaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgdHlwZSB7IFdvcmtzcGFjZUNsaWVudExpa2UgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGV4ZWMgfSBmcm9tIFwiQGRieC10b29scy9jb3JlXCI7XG5pbXBvcnQgeyBEYXRhYnJpY2tzRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL2RhdGFicmlja3NcIjtcbmltcG9ydCB7IGxvY2FsRlMsIHR5cGUgTG9jYWxGaWxlU3lzdGVtIH0gZnJvbSBcIkBkYngtdG9vbHMvZnNcIjtcbmltcG9ydCB7IGZpbmQgfSBmcm9tIFwiQGRieC10b29scy9wYXRoXCI7XG5pbXBvcnQgeyBlcnJvciwgaGFzaCwganNvbiwgbG9nLCBuZXQsIG9iamVjdCwgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgT25lT3JNYW55IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB0eXBlIHsgRmlsZVN5c3RlbSB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1mc1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibWFzdHJhL3JlbW90ZS1za2lsbHNcIik7XG5cbi8qKiBTaGFyZWQgQXNzaXN0YW50IHNraWxscyB0cmVlIGluIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSAoZGVmYXVsdCB0YXJnZXQpLiAqL1xuY29uc3QgQVNTSVNUQU5UX1NIQVJFRF9TS0lMTFNfUEFUSCA9IFwiL1dvcmtzcGFjZS8uYXNzaXN0YW50L3NraWxsc1wiO1xuXG4vKiogQXNzaXN0YW50IHNraWxscyBkaXJlY3RvcnkgZm9yIGEgc3BlY2lmaWMgRGF0YWJyaWNrcyB1c2VyLiAqL1xuZnVuY3Rpb24gdXNlckFzc2lzdGFudFNraWxsc1BhdGgodXNlckVtYWlsOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYC9Vc2Vycy8ke3VzZXJFbWFpbC50cmltKCl9Ly5hc3Npc3RhbnQvc2tpbGxzYDtcbn1cblxuLyoqIG5wbSBhZ2VudCBpZCB0aGUgYHNraWxsc2AgQ0xJIGluc3RhbGxzIGEgYmFyZSBgU0tJTEwubWRgIHRyZWUgdW5kZXIuICovXG5jb25zdCBTS0lMTFNfQ0xJX0FHRU5UID0gXCJhZ2VudHNcIjtcblxuLyoqIFdoZXJlIHRoZSBgc2tpbGxzYCBDTEkgZHJvcHMgYSBwbGFpbiBgU0tJTEwubWRgIHRyZWUgdW5kZXIgYSB0YXJnZXQgZGlyLiAqL1xuY29uc3QgU0tJTExTX0NMSV9MQVlPVVQgPSBbXCIuYWdlbnRzXCIsIFwic2tpbGxzXCJdIGFzIGNvbnN0O1xuXG4vKiogQ2FwIG9uIGEgZGlyZWN0LWZldGNoIGRvd25sb2FkIGJvZHksIG1hdGNoaW5nIHRoZSBgc2tpbGxzYCBDTEkgZGVmYXVsdC4gKi9cbmNvbnN0IERFRkFVTFRfTUFYX0RPV05MT0FEX0JZVEVTID0gMTAgKiAxMDI0ICogMTAyNDtcblxuLyoqIFN0YWJsZSB0ZW1wIGRpcmVjdG9yeSBob2xkaW5nIG9uZSByZWJ1aWx0IHNraWxsIHRyZWUgcGVyIHJlbW90ZSBzb3VyY2UuICovXG5jb25zdCBMT0NBTF9TS0lMTFNfRElSID0gXCJtYXN0cmEtbG9jYWwtc2tpbGxzXCI7XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBBSSBUb29scyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuLyoqXG4gKiBTb3VyY2UgY29uc3RhbnQgc2VsZWN0aW5nIERhdGFicmlja3MnIG93biBBSSBUb29scyBza2lsbCBzZXQuXG4gKlxuICogQGV4YW1wbGVcbiAqIG1hc3RyYSh7IHJlbW90ZVNraWxsczogXCJhaXRvb2xzXCIgfSk7XG4gKi9cbmV4cG9ydCBjb25zdCBBSVRPT0xTX1NPVVJDRSA9IFwiYWl0b29sc1wiO1xuXG4vKiogVGhlIHtAbGluayBBSVRPT0xTX1NPVVJDRX0gbGl0ZXJhbCwgZm9yIGNhbGxlcnMgc3BlbGxpbmcgdGhlIHVuaW9uIG91dC4gKi9cbmV4cG9ydCB0eXBlIEFpVG9vbHNTb3VyY2UgPSB0eXBlb2YgQUlUT09MU19TT1VSQ0U7XG5cbi8qKlxuICogVGhlIFBVQkxJQyByZXBvIGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbGAgc291cmNlcyBmcm9tLiBSZWFkaW5nIGl0XG4gKiBkaXJlY3RseSBpcyB3aGF0IGxldHMgYW4gYXBwIGdldCB0aGUgc2FtZSBza2lsbHMgdGhlIENMSSBpbnN0YWxscyB3aXRob3V0XG4gKiB0aGUgQ0xJIC0gd2hpY2ggYSBEYXRhYnJpY2tzIEFwcCBjb250YWluZXIgZG9lcyBub3Qgc2hpcC5cbiAqL1xuY29uc3QgQUlUT09MU19SRVBPID0gXCJkYXRhYnJpY2tzL2RhdGFicmlja3MtYWdlbnQtc2tpbGxzXCI7XG5cbi8qKiBSZXBvIHJlZiB0aGUgc2tpbGxzIGFyZSByZWFkIGZyb20uIE92ZXJyaWRlIHBlciBzb3VyY2Ugd2l0aCBgcmVmYC4gKi9cbmNvbnN0IEFJVE9PTFNfUkVGID0gXCJtYWluXCI7XG5cbi8qKiBTa2lsbCBmaWxlcyBkb3dubG9hZGVkIGF0IG9uY2U7IHRoZSBzZXQgaXMgfjMwIHNraWxscyBvZiBhIGZldyBmaWxlcyBlYWNoLiAqL1xuY29uc3QgQUlUT09MU19DT05DVVJSRU5DWSA9IDg7XG5cbi8qKiBUaGUgc3Vic2V0IG9mIHRoZSByZXBvJ3MgZ2VuZXJhdGVkIGBtYW5pZmVzdC5qc29uYCB0aGlzIG1vZHVsZSByZWFkcy4gKi9cbmludGVyZmFjZSBBaVRvb2xzTWFuaWZlc3Qge1xuICBza2lsbHM/OiBSZWNvcmQ8c3RyaW5nLCB7IGZpbGVzPzogc3RyaW5nW107IHJlcG9fZGlyPzogc3RyaW5nIH0+O1xufVxuXG4vKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSB0eXBlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG4vKipcbiAqIE9uZSByZW1vdGUgc2tpbGwgc291cmNlIGFuZCBpdHMgcGVyLXNvdXJjZSBwb2xpY3kuXG4gKlxuICogYHNvdXJjZWAgaXMge0BsaW5rIEFJVE9PTFNfU09VUkNFfSBvciBhbnl0aGluZyB0aGUgYHNraWxsc2AgZWNvc3lzdGVtXG4gKiB1bmRlcnN0YW5kczogYSBHaXRIdWIgYG93bmVyL3JlcG9gIHNob3J0aGFuZCwgYSBmdWxsIEdpdEh1YiAvIEdpdExhYiAvIGdpdFxuICogVVJMLCBvciBhIGRpcmVjdCBkb3dubG9hZCBVUkwgdG8gYSBgU0tJTEwubWRgIG9yIGFyY2hpdmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVtb3RlU2tpbGxTb3VyY2VPcHRpb25zIHtcbiAgLyoqIGBcImFpdG9vbHNcImAsIGEgR2l0SHViIHNob3J0aGFuZCwgYSBnaXQgLyBHaXRMYWIgVVJMLCBvciBhIGRvd25sb2FkIFVSTC4gKi9cbiAgc291cmNlOiBuZXQuVXJsTGlrZSB8IEFpVG9vbHNTb3VyY2U7XG4gIC8qKiBJbnN0YWxsIG9ubHkgdGhlc2Ugc2tpbGwgbmFtZXMgZnJvbSB0aGUgc291cmNlLiAqL1xuICBza2lsbHM/OiBzdHJpbmcgfCBzdHJpbmdbXTtcbiAgLyoqIEluY2x1ZGUgZXhwZXJpbWVudGFsIHNraWxscy4gYFwiYWl0b29sc1wiYCBvbmx5LiAqL1xuICBleHBlcmltZW50YWw/OiBib29sZWFuO1xuICAvKiogUGluIHRoZSByZXBvIHJlZiAodGFnIC8gYnJhbmNoIC8gc2hhKS4gYFwiYWl0b29sc1wiYCBvbmx5OyBkZWZhdWx0cyB0byBgbWFpbmAuICovXG4gIHJlZj86IHN0cmluZztcbiAgLyoqIE92ZXJyaWRlIHRoZSBieXRlIGNlaWxpbmcgb24gYSBkaXJlY3QtZmV0Y2ggZG93bmxvYWQgZm9yIHRoaXMgc291cmNlLiAqL1xuICBtYXhEb3dubG9hZEJ5dGVzPzogbnVtYmVyO1xuICAvKipcbiAgICogV2hlbiBgZmFsc2VgLCBhIHNvdXJjZSB0aGF0IGZhaWxzIHRvIHJlc29sdmUgaXMgbG9nZ2VkIGFuZCBza2lwcGVkIGluc3RlYWRcbiAgICogb2YgZmFpbGluZyBhcHAgc3RhcnR1cC4gT3ZlcnJpZGVzIHRoZSB0b3AtbGV2ZWwge0BsaW5rIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMuZmFpbE9uRXJyb3J9LlxuICAgKi9cbiAgZmFpbE9uRXJyb3I/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIEEgcmVtb3RlIHNraWxsIHNvdXJjZTogdGhlIHtAbGluayBBSVRPT0xTX1NPVVJDRX0gY29uc3RhbnQsIGEgVVJMLWxpa2VcbiAqIChzdHJpbmcgLyBgVVJMYCAvIGB7IHVybCB9YCksIG9yIGEge0BsaW5rIFJlbW90ZVNraWxsU291cmNlT3B0aW9uc30gYmFnIHdpdGhcbiAqIHBlci1zb3VyY2UgcG9saWN5LlxuICovXG5leHBvcnQgdHlwZSBSZW1vdGVTa2lsbFNvdXJjZSA9IG5ldC5VcmxMaWtlIHwgQWlUb29sc1NvdXJjZSB8IFJlbW90ZVNraWxsU291cmNlT3B0aW9ucztcblxuLyoqXG4gKiBUaGUgd29ya3NwYWNlIGByZW1vdGVTa2lsbHNgIG9wdGlvbjogb25lIHNvdXJjZSwgYSBub24tZW1wdHkgbGlzdCBvZiB0aGVtLCBvclxuICogYSB7QGxpbmsgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9uc30gYmFnIHdoZW4gdG9wLWxldmVsIHBvbGljeSBpcyBuZWVkZWQuXG4gKi9cbmV4cG9ydCB0eXBlIFJlbW90ZVNraWxsc09wdGlvbiA9XG4gIFJlbW90ZVNraWxsU291cmNlIHwgT25lT3JNYW55PFJlbW90ZVNraWxsU291cmNlPiB8IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnM7XG5cbi8qKiBBIHNvdXJjZSBlbnRyeSB3aXRoIGl0cyBgc291cmNlYCBmbGF0dGVuZWQgdG8gYSBwbGFpbiBzdHJpbmcuICovXG50eXBlIE5vcm1hbGl6ZWRTb3VyY2UgPSBPbWl0PFJlbW90ZVNraWxsU291cmNlT3B0aW9ucywgXCJzb3VyY2VcIj4gJiB7IHNvdXJjZTogc3RyaW5nIH07XG5cbi8qKiBUb3AtbGV2ZWwgcmVtb3RlLXNraWxscyBwcm92aXNpb25pbmcgb3B0aW9ucy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyB7XG4gIC8qKiBTb3VyY2VzIHRvIG1hdGVyaWFsaXplIGF0IHN0YXJ0dXAuICovXG4gIHNvdXJjZXM6IFJlbW90ZVNraWxsU291cmNlIHwgT25lT3JNYW55PFJlbW90ZVNraWxsU291cmNlPjtcbiAgLyoqXG4gICAqIEZhaWwgYXBwIHN0YXJ0dXAgd2hlbiBhIHNvdXJjZSBjYW4ndCBiZSByZXNvbHZlZC4gRGVmYXVsdHMgdG8gYHRydWVgLiBBXG4gICAqIHBlci1zb3VyY2UgYGZhaWxPbkVycm9yYCB3aW5zIG92ZXIgdGhpcy5cbiAgICovXG4gIGZhaWxPbkVycm9yPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIEFic29sdXRlIERhdGFicmlja3MgcGF0aCB0aGF0IHJvb3RzIHRoZSBkZXN0aW5hdGlvbiBBc3Npc3RhbnQgc2tpbGxzIHRyZWUuXG4gICAqIERlZmF1bHRzIHRvIHRoZSBPQk8gdXNlcidzIGAvVXNlcnMvPGVtYWlsPi8uYXNzaXN0YW50L3NraWxsc2AuXG4gICAqL1xuICBkYXRhYnJpY2tzQmFzZVBhdGg/OiBzdHJpbmc7XG4gIC8qKiBBdXRoLXNjb3BlZCBEYXRhYnJpY2tzIGNsaWVudC4gRGVmYXVsdHMgdG8gdGhlIEFwcEtpdCBleGVjdXRpb24gY29udGV4dC4gKi9cbiAgY2xpZW50PzogV29ya3NwYWNlQ2xpZW50TGlrZTtcbiAgLyoqIFVzZXIgZW1haWwgdXNlZCB0byBkZXJpdmUgdGhlIGRlZmF1bHQgRGF0YWJyaWNrcyBkZXN0aW5hdGlvbi4gKi9cbiAgdXNlckVtYWlsPzogc3RyaW5nO1xuICAvKiogQnl0ZSBjZWlsaW5nIG9uIGEgZGlyZWN0LWZldGNoIGRvd25sb2FkLiBEZWZhdWx0cyB0byAxMCBNaUIuICovXG4gIG1heERvd25sb2FkQnl0ZXM/OiBudW1iZXI7XG59XG5cbi8qKiBXaGF0IHtAbGluayBwcm92aXNpb25SZW1vdGVTa2lsbHN9IHJlc29sdmVkLiAqL1xuZXhwb3J0IGludGVyZmFjZSBQcm92aXNpb25lZFJlbW90ZVNraWxscyB7XG4gIC8qKlxuICAgKiBFeHRyYSBMT0NBTCBza2lsbCBzY2FuIHBhdGhzIHRvIGhhbmQgTWFzdHJhIChhIHRlbXAgZGlyIHBlciBzb3VyY2UgdGhhdFxuICAgKiBjb3VsZG4ndCBiZSB3cml0dGVuIHRvIERhdGFicmlja3MpLiBFbXB0eSB3aGVuIGV2ZXJ5dGhpbmcgbGFuZGVkIGluIHRoZVxuICAgKiBEYXRhYnJpY2tzIEFzc2lzdGFudCB0cmVlLCB3aGljaCB0aGUgYnVpbHQtaW4gbW91bnQgYWxyZWFkeSBzY2Fucy5cbiAgICovXG4gIGxvY2FsU2tpbGxQYXRoczogc3RyaW5nW107XG4gIC8qKiBBYnNvbHV0ZSBEYXRhYnJpY2tzIGRlc3RpbmF0aW9uIGVhY2ggc291cmNlIHdhcyB3cml0dGVuIHRvLCBpZiBhbnkuICovXG4gIGRhdGFicmlja3NCYXNlUGF0aD86IHN0cmluZztcbiAgLyoqIE5hbWVzIG9mIGV2ZXJ5IHNraWxsIGRpcmVjdG9yeSB0aGF0IHdhcyBwcm92aXNpb25lZC4gKi9cbiAgc2tpbGxOYW1lczogc3RyaW5nW107XG59XG5cbi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cbi8qKiBOb3JtYWxpemUgdGhlIGByZW1vdGVTa2lsbHNgIG9wdGlvbiBpbnRvIGEgZmxhdCBvcHRpb25zIGJhZy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVSZW1vdGVTa2lsbHNPcHRpb24oXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyB8IHVuZGVmaW5lZCB7XG4gIGlmIChvcHRpb24gPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgYmFnID0gaXNQcm92aXNpb25PcHRpb25zKG9wdGlvbikgPyBvcHRpb24gOiB1bmRlZmluZWQ7XG4gIGNvbnN0IHNvdXJjZXMgPSB0b1NvdXJjZUxpc3QoYmFnID8gYmFnLnNvdXJjZXMgOiAob3B0aW9uIGFzIFJlbW90ZVNraWxsU291cmNlKSk7XG4gIC8vIEFuIGVtcHR5IGxpc3QgaXMgdGhlIHNhbWUgYXMgbm8gY29uZmlndXJhdGlvbiBhdCBhbGwuXG4gIGlmICghb2JqZWN0LmlzT25lT3JNYW55KHNvdXJjZXMpKSByZXR1cm4gdW5kZWZpbmVkO1xuICByZXR1cm4geyAuLi5iYWcsIHNvdXJjZXMgfTtcbn1cblxuLyoqIEEgYHNvdXJjZXNgLWJlYXJpbmcgYmFnIGlzIHRoZSB0b3AtbGV2ZWwgb3B0aW9ucyBzaGFwZSwgbm90IGEgc2luZ2xlIHNvdXJjZS4gKi9cbmZ1bmN0aW9uIGlzUHJvdmlzaW9uT3B0aW9ucyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMge1xuICByZXR1cm4gb2JqZWN0LmlzUmVjb3JkKHZhbHVlKSAmJiBcInNvdXJjZXNcIiBpbiB2YWx1ZTtcbn1cblxuLyoqIE9uZSBzb3VyY2Ugb3IgbWFueSwgYXMgYSBwbGFpbiBhcnJheS4gQSBzb3VyY2UgaXMgbmV2ZXIgaXRzZWxmIGFuIGFycmF5LiAqL1xuZnVuY3Rpb24gdG9Tb3VyY2VMaXN0KFxuICBpbnB1dDogUmVtb3RlU2tpbGxTb3VyY2UgfCBPbmVPck1hbnk8UmVtb3RlU2tpbGxTb3VyY2U+LFxuKTogUmVtb3RlU2tpbGxTb3VyY2VbXSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGlucHV0KSA/IFsuLi5pbnB1dF0gOiBbaW5wdXRdO1xufVxuXG4vKiogRmxhdHRlbiBhIHNvdXJjZSBlbnRyeSAtIHN0cmluZywgYFVSTGAsIGB7IHVybCB9YCwgb3Igb3B0aW9ucyBiYWcgLSB0byBhIHtAbGluayBOb3JtYWxpemVkU291cmNlfS4gKi9cbmZ1bmN0aW9uIHRvU291cmNlT3B0aW9ucyhzb3VyY2U6IFJlbW90ZVNraWxsU291cmNlKTogTm9ybWFsaXplZFNvdXJjZSB7XG4gIGlmICh0eXBlb2Ygc291cmNlID09PSBcInN0cmluZ1wiKSByZXR1cm4geyBzb3VyY2UgfTtcbiAgaWYgKHNvdXJjZSBpbnN0YW5jZW9mIFVSTCkgcmV0dXJuIHsgc291cmNlOiBzb3VyY2UudG9TdHJpbmcoKSB9O1xuICBpZiAoXCJzb3VyY2VcIiBpbiBzb3VyY2UpIHJldHVybiB7IC4uLnNvdXJjZSwgc291cmNlOiB0b1NvdXJjZVN0cmluZyhzb3VyY2Uuc291cmNlKSB9O1xuICByZXR1cm4geyBzb3VyY2U6IHNvdXJjZS51cmwgfTtcbn1cblxuLyoqIEEge0BsaW5rIG5ldC5VcmxMaWtlfSBhcyB0aGUgcGxhaW4gc3RyaW5nIHRoZSBzdGFnaW5nIHBhdGhzIHdvcmsgd2l0aC4gKi9cbmZ1bmN0aW9uIHRvU291cmNlU3RyaW5nKHNvdXJjZTogbmV0LlVybExpa2UpOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJzdHJpbmdcIikgcmV0dXJuIHNvdXJjZTtcbiAgcmV0dXJuIHNvdXJjZSBpbnN0YW5jZW9mIFVSTCA/IHNvdXJjZS50b1N0cmluZygpIDogc291cmNlLnVybDtcbn1cblxuLyoqIFRydWUgd2hlbiBhIHNvdXJjZSBzZWxlY3RzIHRoZSBidWlsdC1pbiBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxsIHNldC4gKi9cbmZ1bmN0aW9uIGlzQWlUb29sc1NvdXJjZShzb3VyY2U6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc291cmNlLnRyaW0oKS50b0xvd2VyQ2FzZSgpID09PSBBSVRPT0xTX1NPVVJDRTtcbn1cblxuLyoqXG4gKiBNYXRlcmlhbGl6ZSBldmVyeSBjb25maWd1cmVkIHJlbW90ZSBza2lsbCBzb3VyY2UgYXQgYXBwIHN0YXJ0dXAuXG4gKlxuICogV3JpdGVzIGVhY2ggcmVzb2x2ZWQgYFNLSUxMLm1kYCB0cmVlIHRvIHRoZSBEYXRhYnJpY2tzIHVzZXIgQXNzaXN0YW50IHNraWxsc1xuICogZm9sZGVyIHdoZW4gYSB3cml0YWJsZSB3b3Jrc3BhY2UgaXMgYXZhaWxhYmxlLCBlbHNlIHVuZGVyXG4gKiB7QGxpbmsgbG9jYWxGUy50bXBGU30gcmV0dXJuZWQgaW4ge0BsaW5rIFByb3Zpc2lvbmVkUmVtb3RlU2tpbGxzLmxvY2FsU2tpbGxQYXRoc30uXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBwcm92aXNpb25SZW1vdGVTa2lsbHMoXG4gIG9wdGlvbjogUmVtb3RlU2tpbGxzT3B0aW9uIHwgdW5kZWZpbmVkLFxuKTogUHJvbWlzZTxQcm92aXNpb25lZFJlbW90ZVNraWxscz4ge1xuICBjb25zdCBvcHRpb25zID0gbm9ybWFsaXplUmVtb3RlU2tpbGxzT3B0aW9uKG9wdGlvbik7XG4gIGNvbnN0IGVtcHR5OiBQcm92aXNpb25lZFJlbW90ZVNraWxscyA9IHsgbG9jYWxTa2lsbFBhdGhzOiBbXSwgc2tpbGxOYW1lczogW10gfTtcbiAgaWYgKCFvcHRpb25zKSByZXR1cm4gZW1wdHk7XG5cbiAgY29uc3QgZmFpbERlZmF1bHQgPSBvcHRpb25zLmZhaWxPbkVycm9yICE9PSBmYWxzZTtcbiAgY29uc3QgY2xpZW50ID0gb3B0aW9ucy5jbGllbnQgPz8gYXBwa2l0LnRyeUdldEV4ZWN1dGlvbkNvbnRleHQoKT8uY2xpZW50O1xuICBjb25zdCBkYXRhYnJpY2tzQmFzZVBhdGggPSByZXNvbHZlRGF0YWJyaWNrc0Jhc2VQYXRoKG9wdGlvbnMsIGNsaWVudCk7XG4gIGNvbnN0IGRlc3RpbmF0aW9uID0gZGF0YWJyaWNrc0Jhc2VQYXRoXG4gICAgPyBuZXcgRGF0YWJyaWNrc0ZpbGVTeXN0ZW0oe1xuICAgICAgICBjbGllbnQ6IGNsaWVudCBhcyBXb3Jrc3BhY2VDbGllbnQsXG4gICAgICAgIHJvb3Q6IGRhdGFicmlja3NCYXNlUGF0aCxcbiAgICAgICAgcmVhZE9ubHk6IGZhbHNlLFxuICAgICAgICBjcmVhdGVSb290OiB0cnVlLFxuICAgICAgfSlcbiAgICA6IHVuZGVmaW5lZDtcblxuICBjb25zdCBsb2NhbFNraWxsUGF0aHM6IHN0cmluZ1tdID0gW107XG4gIGNvbnN0IHNraWxsTmFtZXM6IHN0cmluZ1tdID0gW107XG4gIGxldCBzdGFnaW5nOiBMb2NhbEZpbGVTeXN0ZW0gfCB1bmRlZmluZWQ7XG5cbiAgdHJ5IHtcbiAgICBjb25zdCBzb3VyY2VzID0gQXJyYXkuaXNBcnJheShvcHRpb25zLnNvdXJjZXMpID8gb3B0aW9ucy5zb3VyY2VzIDogW29wdGlvbnMuc291cmNlc107XG4gICAgZm9yIChjb25zdCBlbnRyeSBvZiBzb3VyY2VzKSB7XG4gICAgICBjb25zdCBzb3VyY2VPcHRpb25zID0gdG9Tb3VyY2VPcHRpb25zKGVudHJ5KTtcbiAgICAgIGNvbnN0IGZhaWxPbkVycm9yID0gc291cmNlT3B0aW9ucy5mYWlsT25FcnJvciA/PyBmYWlsRGVmYXVsdDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHN0YWdpbmcgPz89IGF3YWl0IGluaXRpYWxpemVkU2NyYXRjaChcIm1hc3RyYS1yZW1vdGUtc2tpbGxzXCIpO1xuICAgICAgICBjb25zdCBzdGFnZWREaXIgPSBhd2FpdCBzdGFnZVNvdXJjZShzb3VyY2VPcHRpb25zLCBzdGFnaW5nLnJvb3QsIG9wdGlvbnMpO1xuICAgICAgICBjb25zdCBzdGFnZWQgPSBhd2FpdCBjb2xsZWN0U2tpbGxEaXJzKHN0YWdlZERpcik7XG4gICAgICAgIGlmIChzdGFnZWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBubyBTS0lMTC5tZCBmb3VuZCBmb3Igc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cImApO1xuICAgICAgICB9XG4gICAgICAgIGlmIChkZXN0aW5hdGlvbiAmJiBkYXRhYnJpY2tzQmFzZVBhdGgpIHtcbiAgICAgICAgICBhd2FpdCBjb3B5U2tpbGxEaXJzKGRlc3RpbmF0aW9uLCBzdGFnZWQpO1xuICAgICAgICAgIHNraWxsTmFtZXMucHVzaCguLi5zdGFnZWQubWFwKChkaXIpID0+IGRpci5uYW1lKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgbG9jYWxEaXIgPSBhd2FpdCBwZXJzaXN0TG9jYWxseShzb3VyY2VPcHRpb25zLnNvdXJjZSwgc3RhZ2VkKTtcbiAgICAgICAgICBsb2NhbFNraWxsUGF0aHMucHVzaChsb2NhbERpcik7XG4gICAgICAgICAgc2tpbGxOYW1lcy5wdXNoKC4uLnN0YWdlZC5tYXAoKGRpcikgPT4gZGlyLm5hbWUpKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIuZGVidWcoXCJzb3VyY2U6cHJvdmlzaW9uZWRcIiwge1xuICAgICAgICAgIHNvdXJjZTogc291cmNlT3B0aW9ucy5zb3VyY2UsXG4gICAgICAgICAgZGVzdGluYXRpb246IGRhdGFicmlja3NCYXNlUGF0aCA/PyBcImxvY2FsLXRlbXBcIixcbiAgICAgICAgICBza2lsbHM6IHN0YWdlZC5tYXAoKGRpcikgPT4gZGlyLm5hbWUpLFxuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgICBpZiAoZmFpbE9uRXJyb3IpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICBgZmFpbGVkIHRvIHByb3Zpc2lvbiByZW1vdGUgc2tpbGwgc291cmNlIFwiJHtzb3VyY2VPcHRpb25zLnNvdXJjZX1cIjogJHtlcnJvci5lcnJvck1lc3NhZ2UoZXJyKX1gLFxuICAgICAgICAgICAgeyBjYXVzZTogZXJyb3IudG9FcnJvcihlcnIpIH0sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBsb2dnZXIud2FybihcInNvdXJjZTpza2lwcGVkXCIsIHtcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZU9wdGlvbnMuc291cmNlLFxuICAgICAgICAgIGVycm9yOiBlcnJvci5lcnJvck1lc3NhZ2UoZXJyKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGlmIChzdGFnaW5nKSB7XG4gICAgICBhd2FpdCBybShzdGFnaW5nLnJvb3QsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7IGxvY2FsU2tpbGxQYXRocywgZGF0YWJyaWNrc0Jhc2VQYXRoLCBza2lsbE5hbWVzIH07XG59XG5cbi8qKiBSZXNvbHZlIHRoZSBEYXRhYnJpY2tzIEFzc2lzdGFudCBza2lsbHMgZGVzdGluYXRpb24sIG9yIGB1bmRlZmluZWRgIGZvciBsb2NhbCB0ZW1wLiAqL1xuZnVuY3Rpb24gcmVzb2x2ZURhdGFicmlja3NCYXNlUGF0aChcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlIHwgdW5kZWZpbmVkLFxuKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKCFjbGllbnQpIHJldHVybiB1bmRlZmluZWQ7XG4gIGlmIChvcHRpb25zLmRhdGFicmlja3NCYXNlUGF0aCkgcmV0dXJuIG9wdGlvbnMuZGF0YWJyaWNrc0Jhc2VQYXRoLnRyaW0oKSB8fCB1bmRlZmluZWQ7XG4gIGNvbnN0IGVtYWlsID0gc3RyaW5nLnRyaW1Ub051bGwob3B0aW9ucy51c2VyRW1haWwpO1xuICAvLyBBIG5hbWVkIHVzZXIgdGFyZ2V0cyB0aGVpciBwZXJzb25hbCBBc3Npc3RhbnQgdHJlZSAodGhlIFwic2F2ZSBhIHNraWxsXCJcbiAgLy8gdGFyZ2V0KTsgb3RoZXJ3aXNlIHRoZSBzaGFyZWQgd29ya3NwYWNlIEFzc2lzdGFudCB0cmVlLCB3aGljaCB0aGUgYnVpbHQtaW5cbiAgLy8gQXNzaXN0YW50LXNraWxscyBtb3VudCBhbHJlYWR5IHNjYW5zLlxuICByZXR1cm4gZW1haWwgPyB1c2VyQXNzaXN0YW50U2tpbGxzUGF0aChlbWFpbCkgOiBBU1NJU1RBTlRfU0hBUkVEX1NLSUxMU19QQVRIO1xufVxuXG4vKipcbiAqIFN0YWdlIG9uZSBzb3VyY2UgaW50byBhIGZyZXNoIGRpciB1bmRlciBgc3RhZ2luZ1Jvb3RgLCBwcmVmZXJyaW5nIHRoZSBvcHRpb25hbFxuICogYHNraWxsc2AgQ0xJIGFuZCBmYWxsaW5nIGJhY2sgdG8gYSBkaXJlY3QgZmV0Y2guXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHN0YWdlU291cmNlKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICBzdGFnaW5nUm9vdDogc3RyaW5nLFxuICBvcHRpb25zOiBQcm92aXNpb25SZW1vdGVTa2lsbHNPcHRpb25zLFxuKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgY29uc3QgdGFyZ2V0ID0gam9pbihzdGFnaW5nUm9vdCwgYHNyYy0ke2hhc2guaWQoKX1gKTtcbiAgYXdhaXQgbWtkaXIodGFyZ2V0LCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgLy8gQUkgVG9vbHMgcmVzb2x2ZXMgZnJvbSBhIGtub3duIHJlcG8gbGF5b3V0LCBzbyBpdCBuZXZlciBuZWVkcyB0aGUgQ0xJLlxuICBpZiAoaXNBaVRvb2xzU291cmNlKHNvdXJjZU9wdGlvbnMuc291cmNlKSkgcmV0dXJuIHN0YWdlQWlUb29scyhzb3VyY2VPcHRpb25zLCB0YXJnZXQsIG9wdGlvbnMpO1xuICBjb25zdCB2aWFDbGkgPSBhd2FpdCBzdGFnZVZpYVNraWxsc0NsaShzb3VyY2VPcHRpb25zLCB0YXJnZXQpO1xuICBpZiAodmlhQ2xpKSByZXR1cm4gdmlhQ2xpO1xuICByZXR1cm4gc3RhZ2VWaWFGZXRjaChzb3VyY2VPcHRpb25zLCB0YXJnZXQsIG9wdGlvbnMpO1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplIHRoZSBEYXRhYnJpY2tzIEFJIFRvb2xzIHNraWxscyBpbnRvIGB0YXJnZXRgLlxuICpcbiAqIFJlYWRzIHRoZSByZXBvJ3Mgb3duIGdlbmVyYXRlZCBgbWFuaWZlc3QuanNvbmAgKHdoaWNoIG5hbWVzIGVhY2ggc2tpbGwnc1xuICogZmlsZXMgYW5kIHdoZXRoZXIgaXQgbGl2ZXMgdW5kZXIgYHNraWxscy9gIG9yIGBleHBlcmltZW50YWwvYCkgYW5kIGRvd25sb2Fkc1xuICogdGhlbSAtIHRoZSBzYW1lIHRoaW5nIGBkYXRhYnJpY2tzIGFpdG9vbHMgaW5zdGFsbGAgZG9lcywgbWludXMgdGhlIENMSSBhbmRcbiAqIG1pbnVzIGFueSBEYXRhYnJpY2tzIGF1dGgsIHNpbmNlIHRoZSByZXBvIGlzIHB1YmxpYy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhZ2VBaVRvb2xzKFxuICBzb3VyY2VPcHRpb25zOiBOb3JtYWxpemVkU291cmNlLFxuICB0YXJnZXQ6IHN0cmluZyxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IG1heEJ5dGVzID0gcmVzb2x2ZU1heEJ5dGVzKHNvdXJjZU9wdGlvbnMsIG9wdGlvbnMpO1xuICBjb25zdCByZWYgPSBzdHJpbmcudHJpbVRvTnVsbChzb3VyY2VPcHRpb25zLnJlZikgPz8gQUlUT09MU19SRUY7XG4gIGNvbnN0IG1hbmlmZXN0ID0ganNvbi5wYXJzZShcbiAgICAoYXdhaXQgZG93bmxvYWQoYWlUb29sc1Jhd1VybChyZWYsIFwibWFuaWZlc3QuanNvblwiKSwgbWF4Qnl0ZXMpKS50b1N0cmluZyhcInV0ZjhcIiksXG4gICAgdW5kZWZpbmVkLFxuICApIGFzIEFpVG9vbHNNYW5pZmVzdCB8IHVuZGVmaW5lZDtcblxuICBjb25zdCB3YW50ZWQgPSBuZXcgU2V0KHN0cmluZy5wYXJzZUxpc3Qoc291cmNlT3B0aW9ucy5za2lsbHMpKTtcbiAgY29uc3Qgc2VsZWN0ZWQgPSBPYmplY3QuZW50cmllcyhtYW5pZmVzdD8uc2tpbGxzID8/IHt9KS5maWx0ZXIoKFtuYW1lLCBlbnRyeV0pID0+XG4gICAgd2FudGVkLnNpemUgPiAwXG4gICAgICA/IHdhbnRlZC5oYXMobmFtZSlcbiAgICAgIDogZW50cnkucmVwb19kaXIgIT09IFwiZXhwZXJpbWVudGFsXCIgfHwgc291cmNlT3B0aW9ucy5leHBlcmltZW50YWwgPT09IHRydWUsXG4gICk7XG4gIGlmIChzZWxlY3RlZC5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYG5vIG1hdGNoaW5nIHNraWxscyBpbiAke0FJVE9PTFNfUkVQT31AJHtyZWZ9YCk7XG4gIH1cblxuICBjb25zdCBmaWxlcyA9IHNlbGVjdGVkLmZsYXRNYXAoKFtuYW1lLCBlbnRyeV0pID0+XG4gICAgKGVudHJ5LmZpbGVzID8/IFtdKS5tYXAoKGZpbGUpID0+ICh7XG4gICAgICB1cmw6IGFpVG9vbHNSYXdVcmwocmVmLCBgJHtlbnRyeS5yZXBvX2RpciA/PyBcInNraWxsc1wifS8ke25hbWV9LyR7ZmlsZX1gKSxcbiAgICAgIHBhdGg6IGpvaW4odGFyZ2V0LCBuYW1lLCAuLi5maWxlLnNwbGl0KFwiL1wiKSksXG4gICAgfSkpLFxuICApO1xuICBhd2FpdCBtYXBDb25jdXJyZW50KGZpbGVzLCBBSVRPT0xTX0NPTkNVUlJFTkNZLCBhc3luYyAoaXRlbSkgPT4ge1xuICAgIGNvbnN0IGJvZHkgPSBhd2FpdCBkb3dubG9hZChpdGVtLnVybCwgbWF4Qnl0ZXMpO1xuICAgIGF3YWl0IG1rZGlyKGRpcm5hbWUoaXRlbS5wYXRoKSwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gICAgYXdhaXQgd3JpdGVGaWxlKGl0ZW0ucGF0aCwgYm9keSk7XG4gIH0pO1xuXG4gIGxvZ2dlci5kZWJ1ZyhcImFpdG9vbHM6c3RhZ2VkXCIsIHsgcmVmLCBza2lsbHM6IHNlbGVjdGVkLmxlbmd0aCwgZmlsZXM6IGZpbGVzLmxlbmd0aCB9KTtcbiAgcmV0dXJuIHRhcmdldDtcbn1cblxuLyoqIFJhdy1jb250ZW50IFVSTCBmb3IgYSBwYXRoIGluIHRoZSBBSSBUb29scyByZXBvIGF0IGByZWZgLiAqL1xuZnVuY3Rpb24gYWlUb29sc1Jhd1VybChyZWY6IHN0cmluZywgcGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vJHtBSVRPT0xTX1JFUE99LyR7cmVmfS8ke3BhdGh9YDtcbn1cblxuLyoqIFJ1biBgd29ya2VyYCBvdmVyIGBpdGVtc2AsIGF0IG1vc3QgYGxpbWl0YCBpbiBmbGlnaHQuICovXG5hc3luYyBmdW5jdGlvbiBtYXBDb25jdXJyZW50PFQ+KFxuICBpdGVtczogcmVhZG9ubHkgVFtdLFxuICBsaW1pdDogbnVtYmVyLFxuICB3b3JrZXI6IChpdGVtOiBUKSA9PiBQcm9taXNlPHZvaWQ+LFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGxldCBjdXJzb3IgPSAwO1xuICBjb25zdCBydW5uZXJzID0gQXJyYXkuZnJvbSh7IGxlbmd0aDogTWF0aC5taW4obGltaXQsIGl0ZW1zLmxlbmd0aCkgfSwgYXN5bmMgKCkgPT4ge1xuICAgIHdoaWxlIChjdXJzb3IgPCBpdGVtcy5sZW5ndGgpIHtcbiAgICAgIGF3YWl0IHdvcmtlcihpdGVtc1tjdXJzb3IrK10hKTtcbiAgICB9XG4gIH0pO1xuICBhd2FpdCBQcm9taXNlLmFsbChydW5uZXJzKTtcbn1cblxuLyoqXG4gKiBDb3B5IGEgc291cmNlIGludG8gYHRhcmdldGAgd2l0aCB0aGUgYHNraWxsc2AgQ0xJIHdoZW4gaXQgaXMgaW5zdGFsbGVkLlxuICogUmV0dXJucyB0aGUgZGlyIGhvbGRpbmcgdGhlIGNvcGllZCBgU0tJTEwubWRgIHRyZWVzLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZVxuICogQ0xJIGlzIGFic2VudCAoc28gdGhlIGNhbGxlciBjYW4gZmFsbCBiYWNrIHRvIGEgZmV0Y2gpLlxuICovXG5hc3luYyBmdW5jdGlvbiBzdGFnZVZpYVNraWxsc0NsaShcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgdGFyZ2V0OiBzdHJpbmcsXG4pOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCBjbGkgPSBhd2FpdCByZXNvbHZlU2tpbGxzQ2xpKCk7XG4gIGlmICghY2xpKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgLi4uY2xpLmFyZ3MsXG4gICAgXCJhZGRcIixcbiAgICBzb3VyY2VPcHRpb25zLnNvdXJjZSxcbiAgICBcIi0tYWdlbnRcIixcbiAgICBTS0lMTFNfQ0xJX0FHRU5ULFxuICAgIFwiLS1jb3B5XCIsXG4gICAgXCIteVwiLFxuICBdO1xuICBmb3IgKGNvbnN0IHNraWxsIG9mIHN0cmluZy5wYXJzZUxpc3Qoc291cmNlT3B0aW9ucy5za2lsbHMpKSB7XG4gICAgYXJncy5wdXNoKFwiLS1za2lsbFwiLCBza2lsbCk7XG4gIH1cbiAgaWYgKHN0cmluZy5wYXJzZUxpc3Qoc291cmNlT3B0aW9ucy5za2lsbHMpLmxlbmd0aCA9PT0gMCkgYXJncy5wdXNoKFwiLS1za2lsbFwiLCBcIipcIik7XG5cbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgZXhlYy5zcGF3bihjbGkuY29tbWFuZCwgYXJncywge1xuICAgIGN3ZDogdGFyZ2V0LFxuICAgIHN0ZG91dDogXCJjYXB0dXJlXCIsXG4gICAgc3RkZXJyOiBcImNhcHR1cmVcIixcbiAgICBjaGVjazogZmFsc2UsXG4gIH0pO1xuICBpZiAocmVzdWx0LmV4aXRDb2RlICE9PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYHNraWxscyBDTEkgZmFpbGVkIChleGl0ICR7cmVzdWx0LmV4aXRDb2RlfSk6ICR7cmVzdWx0LnN0ZGVyciB8fCByZXN1bHQuc3Rkb3V0fWAsXG4gICAgKTtcbiAgfVxuICByZXR1cm4gam9pbih0YXJnZXQsIC4uLlNLSUxMU19DTElfTEFZT1VUKTtcbn1cblxuLyoqXG4gKiBMb2NhdGUgdGhlIG9wdGlvbmFsIGBza2lsbHNgIENMSSBiaW4sIHJlc29sdmVkIGZyb20gVEhJUyBwYWNrYWdlJ3MgbW9kdWxlXG4gKiBncmFwaC4gUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoZSBwZWVyIGRlcCBpc24ndCBpbnN0YWxsZWQsIHNvIHRoZSBjYWxsZXJcbiAqIGZhbGxzIGJhY2sgdG8gYSBkaXJlY3QgZmV0Y2guXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVTa2lsbHNDbGkoKTogUHJvbWlzZTx7IGNvbW1hbmQ6IHN0cmluZzsgYXJnczogc3RyaW5nW10gfSB8IHVuZGVmaW5lZD4ge1xuICB0cnkge1xuICAgIGNvbnN0IHJlcXVpcmUgPSBjcmVhdGVSZXF1aXJlKGltcG9ydC5tZXRhLnVybCk7XG4gICAgY29uc3QgcGtnUGF0aCA9IHJlcXVpcmUucmVzb2x2ZShcInNraWxscy9wYWNrYWdlLmpzb25cIik7XG4gICAgY29uc3QgYmluID0gam9pbihwa2dQYXRoLCBcIi4uXCIsIFwiYmluXCIsIFwiY2xpLm1qc1wiKTtcbiAgICBpZiAoYXdhaXQgcGF0aEV4aXN0cyhiaW4pKSByZXR1cm4geyBjb21tYW5kOiBwcm9jZXNzLmV4ZWNQYXRoLCBhcmdzOiBbYmluXSB9O1xuICB9IGNhdGNoIHtcbiAgICAvLyBwZWVyIGRlcCBhYnNlbnQgb3IgdW5yZXNvbHZhYmxlIC0gZmV0Y2ggZmFsbGJhY2sgaGFuZGxlcyBpdFxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRmV0Y2ggYSBzb3VyY2UgVVJMIGFuZCB3cml0ZSB0aGUgZG93bmxvYWRlZCBgU0tJTEwubWRgIHVuZGVyIGB0YXJnZXRgLlxuICogVXNlZCB3aGVuIHRoZSBgc2tpbGxzYCBDTEkgaXNuJ3QgaW5zdGFsbGVkOyBzdXBwb3J0cyBhIGRpcmVjdCBgU0tJTEwubWRgIFVSTC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gc3RhZ2VWaWFGZXRjaChcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgdGFyZ2V0OiBzdHJpbmcsXG4gIG9wdGlvbnM6IFByb3Zpc2lvblJlbW90ZVNraWxsc09wdGlvbnMsXG4pOiBQcm9taXNlPHN0cmluZz4ge1xuICBjb25zdCB1cmwgPSBuZXQudXJsQnVpbGRlcihzb3VyY2VPcHRpb25zLnNvdXJjZSk7XG4gIGlmICghdXJsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgYHNvdXJjZSBcIiR7c291cmNlT3B0aW9ucy5zb3VyY2V9XCIgaXMgbm90IGEgVVJMIGFuZCB0aGUgb3B0aW9uYWwgXCJza2lsbHNcIiBwYWNrYWdlIGlzIG5vdCBpbnN0YWxsZWRgLFxuICAgICk7XG4gIH1cbiAgY29uc3QgYnVmZmVyID0gYXdhaXQgZG93bmxvYWQodXJsLnRvU3RyaW5nKCksIHJlc29sdmVNYXhCeXRlcyhzb3VyY2VPcHRpb25zLCBvcHRpb25zKSk7XG4gIGNvbnN0IG5hbWUgPSBzdHJpbmcudG9TbHVnKGRlcml2ZVNraWxsTmFtZSh1cmwudG9TdHJpbmcoKSkpIHx8IFwicmVtb3RlLXNraWxsXCI7XG4gIGNvbnN0IHNraWxsRGlyID0gam9pbih0YXJnZXQsIG5hbWUpO1xuICBhd2FpdCBta2Rpcihza2lsbERpciwgeyByZWN1cnNpdmU6IHRydWUgfSk7XG4gIGF3YWl0IHdyaXRlRmlsZShqb2luKHNraWxsRGlyLCBcIlNLSUxMLm1kXCIpLCBidWZmZXIpO1xuICByZXR1cm4gdGFyZ2V0O1xufVxuXG4vKiogVGhlIGVmZmVjdGl2ZSBkb3dubG9hZCBjZWlsaW5nOiBwZXItc291cmNlLCB0aGVuIHRvcC1sZXZlbCwgdGhlbiB0aGUgZGVmYXVsdC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVNYXhCeXRlcyhcbiAgc291cmNlT3B0aW9uczogTm9ybWFsaXplZFNvdXJjZSxcbiAgb3B0aW9uczogUHJvdmlzaW9uUmVtb3RlU2tpbGxzT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIHJldHVybiBzb3VyY2VPcHRpb25zLm1heERvd25sb2FkQnl0ZXMgPz8gb3B0aW9ucy5tYXhEb3dubG9hZEJ5dGVzID8/IERFRkFVTFRfTUFYX0RPV05MT0FEX0JZVEVTO1xufVxuXG4vKiogR0VUIGEgVVJMLCBmYWlsaW5nIGxvdWRseSBvbiBhIG5vbi0yeHggc3RhdHVzIG9yIGFuIG92ZXJzaXplZCBib2R5LiAqL1xuYXN5bmMgZnVuY3Rpb24gZG93bmxvYWQodXJsOiBzdHJpbmcsIG1heEJ5dGVzOiBudW1iZXIpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKHVybCk7XG4gIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRvd25sb2FkIGZhaWxlZDogJHtyZXNwb25zZS5zdGF0dXN9ICR7cmVzcG9uc2Uuc3RhdHVzVGV4dH0gKCR7dXJsfSlgKTtcbiAgfVxuICBjb25zdCBidWZmZXIgPSBCdWZmZXIuZnJvbShhd2FpdCByZXNwb25zZS5hcnJheUJ1ZmZlcigpKTtcbiAgaWYgKGJ1ZmZlci5ieXRlTGVuZ3RoID4gbWF4Qnl0ZXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGRvd25sb2FkIGV4Y2VlZHMgJHttYXhCeXRlc30gYnl0ZXMgKCR7dXJsfSlgKTtcbiAgfVxuICByZXR1cm4gYnVmZmVyO1xufVxuXG4vKiogRGVyaXZlIGEgc2tpbGwgZGlyZWN0b3J5IG5hbWUgZnJvbSBhIGRvd25sb2FkIFVSTCdzIGxhc3QgcGF0aCBzZWdtZW50LiAqL1xuZnVuY3Rpb24gZGVyaXZlU2tpbGxOYW1lKHVybFN0cmluZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdXJsID0gbmV0LnVybEJ1aWxkZXIodXJsU3RyaW5nKTtcbiAgY29uc3QgbGFzdCA9IHVybD8ucGF0aG5hbWUuc3BsaXQoXCIvXCIpLmZpbHRlcihCb29sZWFuKS5wb3AoKSA/PyBcIlwiO1xuICByZXR1cm4gbGFzdC5yZXBsYWNlKC9cXC4obWR8emlwfHRhcnx0Z3p8Z3opJC9pLCBcIlwiKTtcbn1cblxuLyoqIEEgc2tpbGwgZGlyZWN0b3J5IChob2xkaW5nIGEgYFNLSUxMLm1kYCkgc3RhZ2VkIG9uIGxvY2FsIGRpc2suICovXG5pbnRlcmZhY2UgU3RhZ2VkU2tpbGxEaXIge1xuICBuYW1lOiBzdHJpbmc7XG4gIGFic29sdXRlUGF0aDogc3RyaW5nO1xufVxuXG4vKipcbiAqIENvbGxlY3QgZXZlcnkgc2tpbGwgZGlyZWN0b3J5IHVuZGVyIGByb290YDogYSBgcm9vdC9TS0lMTC5tZGAgKHJvb3QgSVMgdGhlXG4gKiBza2lsbCkgb3IgZWFjaCBpbW1lZGlhdGUgY2hpbGQgZGlyIHRoYXQgY29udGFpbnMgYSBgU0tJTEwubWRgLlxuICovXG5hc3luYyBmdW5jdGlvbiBjb2xsZWN0U2tpbGxEaXJzKHJvb3Q6IHN0cmluZyk6IFByb21pc2U8U3RhZ2VkU2tpbGxEaXJbXT4ge1xuICBpZiAoIShhd2FpdCBwYXRoRXhpc3RzKHJvb3QpKSkgcmV0dXJuIFtdO1xuICBpZiAoYXdhaXQgcGF0aEV4aXN0cyhqb2luKHJvb3QsIFwiU0tJTEwubWRcIikpKSB7XG4gICAgY29uc3QgbmFtZSA9IHBvc2l4LmJhc2VuYW1lKHJvb3Quc3BsaXQoL1tcXFxcL10vKS5qb2luKFwiL1wiKSk7XG4gICAgcmV0dXJuIFt7IG5hbWUsIGFic29sdXRlUGF0aDogcm9vdCB9XTtcbiAgfVxuICBjb25zdCBkaXJzOiBTdGFnZWRTa2lsbERpcltdID0gW107XG4gIGZvciAoY29uc3QgZW50cnkgb2YgYXdhaXQgcmVhZGRpcihyb290LCB7IHdpdGhGaWxlVHlwZXM6IHRydWUgfSkpIHtcbiAgICBpZiAoIWVudHJ5LmlzRGlyZWN0b3J5KCkpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGRpciA9IGpvaW4ocm9vdCwgZW50cnkubmFtZSk7XG4gICAgaWYgKGF3YWl0IHBhdGhFeGlzdHMoam9pbihkaXIsIFwiU0tJTEwubWRcIikpKSB7XG4gICAgICBkaXJzLnB1c2goeyBuYW1lOiBlbnRyeS5uYW1lLCBhYnNvbHV0ZVBhdGg6IGRpciB9KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGRpcnM7XG59XG5cbi8qKlxuICogQ29weSBldmVyeSBzdGFnZWQgc2tpbGwgZGlyZWN0b3J5IGludG8ge0BsaW5rIGRlc3RpbmF0aW9ufSwgcHJlc2VydmluZyB0aGVcbiAqIGA8c2tpbGw+LzxyZWxhdGl2ZT5gIGxheW91dC4gVGhlIGRlc3RpbmF0aW9uIGlzIGp1c3QgYSB7QGxpbmsgRmlsZVN5c3RlbX0sXG4gKiBzbyB0aGUgRGF0YWJyaWNrcyBBc3Npc3RhbnQgdHJlZSBhbmQgdGhlIGxvY2FsIGZhbGxiYWNrIHNoYXJlIG9uZSBjb3BpZXIuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGNvcHlTa2lsbERpcnMoZGVzdGluYXRpb246IEZpbGVTeXN0ZW0sIGRpcnM6IFN0YWdlZFNraWxsRGlyW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgZGVzdGluYXRpb24uaW5pdCgpO1xuICBmb3IgKGNvbnN0IGRpciBvZiBkaXJzKSB7XG4gICAgZm9yIChjb25zdCByZWxhdGl2ZSBvZiBmaW5kLmZpbmRGaWxlcyhcIioqLypcIiwgeyBjd2Q6IGRpci5hYnNvbHV0ZVBhdGgsIG5vZGlyOiB0cnVlIH0pKSB7XG4gICAgICBjb25zdCBidWZmZXIgPSBhd2FpdCByZWFkRmlsZShqb2luKGRpci5hYnNvbHV0ZVBhdGgsIHJlbGF0aXZlKSk7XG4gICAgICBjb25zdCBza2lsbFBhdGggPSBwb3NpeC5qb2luKGRpci5uYW1lLCByZWxhdGl2ZS5zcGxpdCgvW1xcXFwvXS8pLmpvaW4oXCIvXCIpKTtcbiAgICAgIGF3YWl0IGRlc3RpbmF0aW9uLndyaXRlRmlsZShza2lsbFBhdGgsIGJ1ZmZlciwgeyBvdmVyd3JpdGU6IHRydWUgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29weSBzdGFnZWQgc2tpbGwgZGlycyBpbnRvIGEgU1RBQkxFIGxvY2FsIHRyZWUga2V5ZWQgYnkgdGhlIHNvdXJjZSwgYW5kXG4gKiByZXR1cm4gaXRzIHJvb3QgcGF0aC5cbiAqXG4gKiBBIGdpdmVuIHNvdXJjZSByZXNvbHZlcyB0byB0aGUgc2FtZSBjb250ZW50IG9uIGFsbW9zdCBldmVyeSBib290LCBzbyBlYWNoXG4gKiBvbmUgb3ducyBhIGRpcmVjdG9yeSBuYW1lZCBmb3IgaXRzIHtAbGluayBoYXNoLmZudkhhc2h9IHJhdGhlciB0aGFuIGxlYXZpbmdcbiAqIGEgZnJlc2ggc2NyYXRjaCBkaXIgYmVoaW5kIHBlciByZXN0YXJ0LiBLZXlpbmcgb24gdGhlIHNvdXJjZSAobm90IHRoZVxuICogY29udGVudCkgaXMgd2hhdCBrZWVwcyB0d28gZGlmZmVyZW50IHNvdXJjZXMgZnJvbSBvdmVyd3JpdGluZyBlYWNoIG90aGVyLlxuICovXG5hc3luYyBmdW5jdGlvbiBwZXJzaXN0TG9jYWxseShzb3VyY2U6IHN0cmluZywgZGlyczogU3RhZ2VkU2tpbGxEaXJbXSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHN0YWJsZSA9IGF3YWl0IGxvY2FsRlMucmVidWlsZEZTKGAke0xPQ0FMX1NLSUxMU19ESVJ9LyR7aGFzaC5mbnZIYXNoKHNvdXJjZSl9YCwgKHNjcmF0Y2gpID0+XG4gICAgY29weVNraWxsRGlycyhzY3JhdGNoLCBkaXJzKSxcbiAgKTtcbiAgcmV0dXJuIHN0YWJsZS5yb290O1xufVxuXG4vKipcbiAqIEEgc2NyYXRjaCBmaWxlc3lzdGVtIHdob3NlIHJvb3QgZXhpc3RzIG9uIGRpc2ssIGZvciB0aGUgcGF0aHMgdGhhdCBoYW5kIGFcbiAqIHJlYWwgZGlyZWN0b3J5IHRvIGBub2RlOmZzYCBvciBhIGNoaWxkIHByb2Nlc3MgcmF0aGVyIHRoYW4gZ29pbmcgdGhyb3VnaFxuICogdGhlIHtAbGluayBGaWxlU3lzdGVtfSBBUEkuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGluaXRpYWxpemVkU2NyYXRjaChwcmVmaXg6IHN0cmluZyk6IFByb21pc2U8TG9jYWxGaWxlU3lzdGVtPiB7XG4gIGNvbnN0IHNjcmF0Y2ggPSBsb2NhbEZTLnNjcmF0Y2hGUyhwcmVmaXgpO1xuICBhd2FpdCBzY3JhdGNoLmluaXQoKTtcbiAgcmV0dXJuIHNjcmF0Y2g7XG59XG5cbi8qKiBCZXN0LWVmZm9ydCBleGlzdGVuY2UgY2hlY2suICovXG5hc3luYyBmdW5jdGlvbiBwYXRoRXhpc3RzKHBhdGg6IHN0cmluZyk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICB0cnkge1xuICAgIGF3YWl0IHN0YXQocGF0aCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufVxuIl19
@@ -7,6 +7,10 @@
7
7
  * contributions merge extra filesystems and skill scan roots; built-in
8
8
  * Assistant skill trees are toggled with `assistantSkills` (on by default).
9
9
  *
10
+ * Databricks mounts use `@dbx-tools/databricks` {@link DatabricksFileSystem}
11
+ * wrapped by {@link filesystems}; missing roots fall back to
12
+ * {@link scratchFilesystem}.
13
+ *
10
14
  * @module
11
15
  */
12
16
  import type { RequestContext } from "@mastra/core/request-context";