@dbx-tools/core 0.6.86 → 0.6.88
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -6
- package/lib/src/config.d.ts +34 -3
- package/lib/src/config.js +163 -33
- package/package.json +11 -2
- package/src/config.ts +165 -33
package/README.md
CHANGED
|
@@ -16,8 +16,8 @@ Key features:
|
|
|
16
16
|
- Workspace/project root discovery from package-manager files, git metadata, and
|
|
17
17
|
the current working directory.
|
|
18
18
|
- Safe filesystem stat and project naming helpers for CLIs and projen synth.
|
|
19
|
-
- Layered config from process env, environment-specific `.env` files, and
|
|
20
|
-
Databricks bundle App config
|
|
19
|
+
- Layered config from process env, environment-specific `.env` files, and the
|
|
20
|
+
Databricks bundle's App `config.env`.
|
|
21
21
|
- YAML/JSON brand-context discovery and loading with shared Zod validation.
|
|
22
22
|
- Idempotent executable downloads with zip/tar extraction and atomic installs.
|
|
23
23
|
- Cross-process file locks with a Bun `flock(2)` fast path and a portable,
|
|
@@ -98,10 +98,27 @@ are checked before `.env` when `NODE_ENV=production`; development uses
|
|
|
98
98
|
`.env.development` and `.env.dev`.
|
|
99
99
|
|
|
100
100
|
Bundle lookup runs `databricks bundle validate --output json` only after earlier
|
|
101
|
-
sources miss. It reads literal values from the single App's `config.env
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
sources miss. It reads literal values from the single App's `config.env`, accepts
|
|
102
|
+
usable partial JSON from a failed validation, and caches each dotenv file or
|
|
103
|
+
validated bundle once per resolved working-directory context. Bundle cache
|
|
104
|
+
entries also include the Databricks profile. Root bundle `variables` are NOT a
|
|
105
|
+
config source: they are authoring inputs interpolated into the bundle's own
|
|
106
|
+
targets, resources, and paths, so reading one as a process setting resolves names
|
|
107
|
+
the deployed App never sees. Reference a variable from `config.env` to make it
|
|
108
|
+
one.
|
|
109
|
+
|
|
110
|
+
Because validation is a process spawn, it is gated on this being an AppKit
|
|
111
|
+
project at all, in three steps. `@databricks/appkit` must be RESOLVABLE - it is
|
|
112
|
+
an optional peer, the probe resolves the path without evaluating the module, and
|
|
113
|
+
a consumer that never installed it never spawns the CLI. The bundle must then
|
|
114
|
+
describe exactly ONE app carrying `config.env`, since nothing in this package
|
|
115
|
+
says which of several apps a process is. Finally AppKit's execution context
|
|
116
|
+
confirms the process really is that app; that context does not exist until AppKit
|
|
117
|
+
boots, so only the affirmative is remembered and a lookup during boot still
|
|
118
|
+
resolves from the bundle instead of being permanently denied. Setting
|
|
119
|
+
`DBX_TOOLS_CONFIG_BUNDLE=true` skips this gate for a tool that wants the bundle
|
|
120
|
+
without being the App.
|
|
121
|
+
|
|
105
122
|
Deployed Apps skip dotenv and bundle lookup after `isDatabricksAppEnv()`
|
|
106
123
|
recognizes the required App name, HTTP(S) host, and valid port. Set
|
|
107
124
|
`DBX_TOOLS_DATABRICKS_APP_ENV=true` or `false` to force that result; unrecognized
|
package/lib/src/config.d.ts
CHANGED
|
@@ -20,6 +20,29 @@
|
|
|
20
20
|
* CLI is not on the image. Boolean environment overrides can force either file
|
|
21
21
|
* source on or off when a tool needs different behavior.
|
|
22
22
|
*
|
|
23
|
+
* The bundle is gated on this being an AppKit project at all. `databricks bundle
|
|
24
|
+
* validate` is a process spawn measured in seconds, and a plain library or CLI
|
|
25
|
+
* consumer has no bundle to find, so the gate runs in three steps before the
|
|
26
|
+
* spawn is allowed - see {@link bundleFile}:
|
|
27
|
+
*
|
|
28
|
+
* 1. `@databricks/appkit` is resolved WITHOUT evaluating it. It is an optional
|
|
29
|
+
* peer, so a consumer that never installed it is not an AppKit project and
|
|
30
|
+
* the bundle is never loaded. The probe is cached, so this costs one
|
|
31
|
+
* resolution for the life of the process.
|
|
32
|
+
* 2. The bundle is read (once per context) and must describe EXACTLY ONE app
|
|
33
|
+
* with `config.env`. Nothing here says which of several apps this process
|
|
34
|
+
* is, so an ambiguous bundle contributes nothing rather than a guess.
|
|
35
|
+
* 3. AppKit's execution context confirms this process really is that app. The
|
|
36
|
+
* context does not exist until AppKit boots and `getExecutionContext()`
|
|
37
|
+
* THROWS until then, so the probe is caught and only the affirmative is
|
|
38
|
+
* remembered - a lookup before boot still resolves, and re-confirms later
|
|
39
|
+
* once the context is available.
|
|
40
|
+
*
|
|
41
|
+
* Only the single app's `config.env` is consulted. Root bundle `variables` are
|
|
42
|
+
* not: they are authoring inputs for the bundle itself (interpolated into
|
|
43
|
+
* targets, resources, and paths), so treating one as a process setting resolves
|
|
44
|
+
* names the deployed app never sees.
|
|
45
|
+
*
|
|
23
46
|
* Node-only (`child_process`, `fs`, `process`).
|
|
24
47
|
*
|
|
25
48
|
* @module
|
|
@@ -147,9 +170,17 @@ export declare function list(configured: string | readonly string[] | undefined
|
|
|
147
170
|
/**
|
|
148
171
|
* The Databricks bundle output for `cwd` - `databricks bundle validate --output
|
|
149
172
|
* json` run from the directory holding `databricks.yml`, with the config file's
|
|
150
|
-
* path. A non-zero validation may still return partial JSON with usable
|
|
151
|
-
*
|
|
152
|
-
* the
|
|
173
|
+
* path. A non-zero validation may still return partial JSON with usable App
|
|
174
|
+
* config. `undefined` when bundle reads are disabled, this is not an AppKit
|
|
175
|
+
* project, the bundle does not describe exactly one app with `config.env`, there
|
|
176
|
+
* is no bundle, or the CLI produces no JSON.
|
|
177
|
+
*
|
|
178
|
+
* The spawn is guarded because it is expensive and usually pointless. In order:
|
|
179
|
+
* `@databricks/appkit` must be RESOLVABLE (no AppKit, no bundle - and the probe
|
|
180
|
+
* never evaluates the module); the bundle must describe exactly ONE app carrying
|
|
181
|
+
* `config.env`; and AppKit's execution context must confirm this process is that
|
|
182
|
+
* app. Only the confirmation is remembered, so a lookup during boot - before any
|
|
183
|
+
* context exists - still resolves from the bundle and re-confirms later.
|
|
153
184
|
*
|
|
154
185
|
* Cached once per resolved working-directory context and
|
|
155
186
|
* `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
|
package/lib/src/config.js
CHANGED
|
@@ -20,15 +20,47 @@
|
|
|
20
20
|
* CLI is not on the image. Boolean environment overrides can force either file
|
|
21
21
|
* source on or off when a tool needs different behavior.
|
|
22
22
|
*
|
|
23
|
+
* The bundle is gated on this being an AppKit project at all. `databricks bundle
|
|
24
|
+
* validate` is a process spawn measured in seconds, and a plain library or CLI
|
|
25
|
+
* consumer has no bundle to find, so the gate runs in three steps before the
|
|
26
|
+
* spawn is allowed - see {@link bundleFile}:
|
|
27
|
+
*
|
|
28
|
+
* 1. `@databricks/appkit` is resolved WITHOUT evaluating it. It is an optional
|
|
29
|
+
* peer, so a consumer that never installed it is not an AppKit project and
|
|
30
|
+
* the bundle is never loaded. The probe is cached, so this costs one
|
|
31
|
+
* resolution for the life of the process.
|
|
32
|
+
* 2. The bundle is read (once per context) and must describe EXACTLY ONE app
|
|
33
|
+
* with `config.env`. Nothing here says which of several apps this process
|
|
34
|
+
* is, so an ambiguous bundle contributes nothing rather than a guess.
|
|
35
|
+
* 3. AppKit's execution context confirms this process really is that app. The
|
|
36
|
+
* context does not exist until AppKit boots and `getExecutionContext()`
|
|
37
|
+
* THROWS until then, so the probe is caught and only the affirmative is
|
|
38
|
+
* remembered - a lookup before boot still resolves, and re-confirms later
|
|
39
|
+
* once the context is available.
|
|
40
|
+
*
|
|
41
|
+
* Only the single app's `config.env` is consulted. Root bundle `variables` are
|
|
42
|
+
* not: they are authoring inputs for the bundle itself (interpolated into
|
|
43
|
+
* targets, resources, and paths), so treating one as a process setting resolves
|
|
44
|
+
* names the deployed app never sees.
|
|
45
|
+
*
|
|
23
46
|
* Node-only (`child_process`, `fs`, `process`).
|
|
24
47
|
*
|
|
25
48
|
* @module
|
|
26
49
|
*/
|
|
50
|
+
var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExtension) || function (path, preserveJsx) {
|
|
51
|
+
if (typeof path === "string" && /^\.\.?\//.test(path)) {
|
|
52
|
+
return path.replace(/\.(tsx)$|((?:\.d)?)((?:\.[^./]+?)?)\.([cm]?)ts$/i, function (m, tsx, d, ext, cm) {
|
|
53
|
+
return tsx ? preserveJsx ? ".jsx" : ".js" : d && (!ext || !cm) ? m : (d + ext + "." + cm.toLowerCase() + "js");
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
return path;
|
|
57
|
+
};
|
|
27
58
|
import { spawnSync } from "node:child_process";
|
|
28
59
|
import { readFileSync } from "node:fs";
|
|
60
|
+
import { createRequire } from "node:module";
|
|
29
61
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
30
62
|
import { parseEnv } from "node:util";
|
|
31
|
-
import { context, json, log, object, string as stringModule } from "@dbx-tools/shared-core";
|
|
63
|
+
import { context, functionModule, json, log, object, string as stringModule, } from "@dbx-tools/shared-core";
|
|
32
64
|
import { z } from "zod";
|
|
33
65
|
import { statSync } from "./file.js";
|
|
34
66
|
import { root as resolveProjectRoot } from "./project.js";
|
|
@@ -49,6 +81,20 @@ export const DATABRICKS_APP_ENV_KEY = "DBX_TOOLS_DATABRICKS_APP_ENV";
|
|
|
49
81
|
export const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
|
|
50
82
|
/** Boolean environment override for Databricks bundle reads. */
|
|
51
83
|
export const CONFIG_BUNDLE_KEY = "DBX_TOOLS_CONFIG_BUNDLE";
|
|
84
|
+
/**
|
|
85
|
+
* The OPTIONAL AppKit peer whose presence marks this as a Databricks App
|
|
86
|
+
* project. Held as a constant so the resolve probe and the lazy import name it
|
|
87
|
+
* once, and so neither site carries a literal a bundler would try to follow.
|
|
88
|
+
*/
|
|
89
|
+
const APPKIT_MODULE = "@databricks/appkit";
|
|
90
|
+
/**
|
|
91
|
+
* Whether AppKit's execution context has EVER been observed. Latching is the
|
|
92
|
+
* point: a context confirms this process is the bundle's app, and that fact does
|
|
93
|
+
* not stop being true when a later lookup happens outside a request scope.
|
|
94
|
+
*/
|
|
95
|
+
let appKitContext = false;
|
|
96
|
+
/** Flattened App `config.env` per parsed bundle - see {@link bundleApp}. */
|
|
97
|
+
const BUNDLE_APP_CACHE = new WeakMap();
|
|
52
98
|
/** Exact process-environment lookup for callers that do not read local config files. */
|
|
53
99
|
export const ENV_ONLY = { scope: [], sources: "env" };
|
|
54
100
|
export const bundleValue = z
|
|
@@ -71,10 +117,6 @@ export const bundleEnvEntrySchema = z.object({
|
|
|
71
117
|
value: z.string().optional(),
|
|
72
118
|
value_from: bundleValue.optional(),
|
|
73
119
|
});
|
|
74
|
-
const bundleVariableSchema = z.object({
|
|
75
|
-
default: z.string().optional(),
|
|
76
|
-
value: z.string().optional(),
|
|
77
|
-
});
|
|
78
120
|
export const bundleAppSchema = z.object({
|
|
79
121
|
name: bundleValue.optional(),
|
|
80
122
|
source_code_path: z.string().optional(),
|
|
@@ -84,9 +126,6 @@ export const bundleAppSchema = z.object({
|
|
|
84
126
|
const bundleAppsSchema = z.object({
|
|
85
127
|
resources: z.object({ apps: z.record(z.string(), bundleAppSchema).optional() }).optional(),
|
|
86
128
|
});
|
|
87
|
-
const bundleVariablesSchema = z.object({
|
|
88
|
-
variables: z.record(z.string(), bundleVariableSchema).optional(),
|
|
89
|
-
});
|
|
90
129
|
/**
|
|
91
130
|
* Detect a Databricks App runtime from its required name, host, and port.
|
|
92
131
|
*
|
|
@@ -254,9 +293,17 @@ function toPositiveNumber(value) {
|
|
|
254
293
|
/**
|
|
255
294
|
* The Databricks bundle output for `cwd` - `databricks bundle validate --output
|
|
256
295
|
* json` run from the directory holding `databricks.yml`, with the config file's
|
|
257
|
-
* path. A non-zero validation may still return partial JSON with usable
|
|
258
|
-
*
|
|
259
|
-
* the
|
|
296
|
+
* path. A non-zero validation may still return partial JSON with usable App
|
|
297
|
+
* config. `undefined` when bundle reads are disabled, this is not an AppKit
|
|
298
|
+
* project, the bundle does not describe exactly one app with `config.env`, there
|
|
299
|
+
* is no bundle, or the CLI produces no JSON.
|
|
300
|
+
*
|
|
301
|
+
* The spawn is guarded because it is expensive and usually pointless. In order:
|
|
302
|
+
* `@databricks/appkit` must be RESOLVABLE (no AppKit, no bundle - and the probe
|
|
303
|
+
* never evaluates the module); the bundle must describe exactly ONE app carrying
|
|
304
|
+
* `config.env`; and AppKit's execution context must confirm this process is that
|
|
305
|
+
* app. Only the confirmation is remembered, so a lookup during boot - before any
|
|
306
|
+
* context exists - still resolves from the bundle and re-confirms later.
|
|
260
307
|
*
|
|
261
308
|
* Cached once per resolved working-directory context and
|
|
262
309
|
* `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
|
|
@@ -265,10 +312,33 @@ function toPositiveNumber(value) {
|
|
|
265
312
|
*/
|
|
266
313
|
export function bundleFile(cwd) {
|
|
267
314
|
const production = process.env.NODE_ENV?.trim().toLowerCase() === "production";
|
|
268
|
-
|
|
315
|
+
const override = object.toBoolean(process.env[CONFIG_BUNDLE_KEY]);
|
|
316
|
+
if (override === false)
|
|
269
317
|
return undefined;
|
|
318
|
+
// An explicit `true` is the escape hatch for a tool that wants the bundle
|
|
319
|
+
// without being the app (`dbx` commands, tests), so it skips the AppKit gate
|
|
320
|
+
// entirely - but not the App/production defaults, which it also overrides.
|
|
321
|
+
if (override === undefined) {
|
|
322
|
+
if (production || isDatabricksAppEnv())
|
|
323
|
+
return undefined;
|
|
324
|
+
if (!appKitInstalled())
|
|
325
|
+
return undefined;
|
|
326
|
+
}
|
|
270
327
|
const profile = stringModule.trimToNull(process.env.DATABRICKS_CONFIG_PROFILE);
|
|
271
|
-
|
|
328
|
+
const file = cachedConfig(["bundle", profile ?? ""], cwd, (resolved) => loadBundleFile(resolved, profile));
|
|
329
|
+
if (override !== undefined || file === undefined)
|
|
330
|
+
return file;
|
|
331
|
+
// Already confirmed: this process is the app, and that does not stop being
|
|
332
|
+
// true, so skip re-deriving the gate on every lookup.
|
|
333
|
+
if (appKitContext)
|
|
334
|
+
return file;
|
|
335
|
+
// The app must be unambiguous. `bundleApp` is what decides "exactly one app
|
|
336
|
+
// with `config.env`", so an empty map IS the ambiguous or app-less bundle and
|
|
337
|
+
// needs no separate check.
|
|
338
|
+
if (Object.keys(bundleApp(file.data)).length === 0)
|
|
339
|
+
return undefined;
|
|
340
|
+
confirmAppKitContext();
|
|
341
|
+
return file;
|
|
272
342
|
}
|
|
273
343
|
/**
|
|
274
344
|
* The single App's literal `config.env` entries, flattened to `name -> value`.
|
|
@@ -279,8 +349,24 @@ export function bundleFile(cwd) {
|
|
|
279
349
|
* {@link bundleResourceSchema}. An `apps` block with more than one app is
|
|
280
350
|
* ambiguous (nothing here says which app this process is), so it yields nothing
|
|
281
351
|
* rather than a guess.
|
|
352
|
+
*
|
|
353
|
+
* Memoized against the parsed bundle it came from, because both the gate in
|
|
354
|
+
* {@link bundleFile} and the lookup in {@link read} ask the same question of the
|
|
355
|
+
* same cached object - validating that payload twice per lookup would be pure
|
|
356
|
+
* waste. A `WeakMap` keeps the entry alive exactly as long as the bundle is.
|
|
282
357
|
*/
|
|
283
358
|
function bundleApp(input) {
|
|
359
|
+
if (!object.isRecord(input))
|
|
360
|
+
return bundleAppEntries(input);
|
|
361
|
+
const cached = BUNDLE_APP_CACHE.get(input);
|
|
362
|
+
if (cached)
|
|
363
|
+
return cached;
|
|
364
|
+
const result = bundleAppEntries(input);
|
|
365
|
+
BUNDLE_APP_CACHE.set(input, result);
|
|
366
|
+
return result;
|
|
367
|
+
}
|
|
368
|
+
/** {@link bundleApp} without the memoization, so the cache has one filler. */
|
|
369
|
+
function bundleAppEntries(input) {
|
|
284
370
|
const parsed = bundleAppsSchema.safeParse(input);
|
|
285
371
|
if (!parsed.success)
|
|
286
372
|
return {};
|
|
@@ -302,25 +388,71 @@ function bundleApp(input) {
|
|
|
302
388
|
return result;
|
|
303
389
|
}
|
|
304
390
|
/**
|
|
305
|
-
*
|
|
391
|
+
* Whether `@databricks/appkit` can be RESOLVED from this process, cached for its
|
|
392
|
+
* lifetime.
|
|
306
393
|
*
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
394
|
+
* Resolution, not import: this answers "is this an AppKit project" without
|
|
395
|
+
* evaluating the module, so the cheap negative (a plain library or CLI consumer
|
|
396
|
+
* that never installed the optional peer) costs one path lookup and never boots
|
|
397
|
+
* AppKit as a side effect of reading config. A runtime with no `createRequire`
|
|
398
|
+
* (a browser bundle that reached this Node-only module anyway) reports absent.
|
|
311
399
|
*/
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
const value = resolvedString(variable.value) ?? resolvedString(variable.default);
|
|
320
|
-
if (key && value !== null)
|
|
321
|
-
result[key] = value;
|
|
400
|
+
const appKitInstalled = functionModule.memoize(() => {
|
|
401
|
+
try {
|
|
402
|
+
// Indirect specifier: a bundler must not try to follow an OPTIONAL peer that
|
|
403
|
+
// a browser build has no way to resolve.
|
|
404
|
+
const specifier = APPKIT_MODULE;
|
|
405
|
+
createRequire(import.meta.url).resolve(specifier);
|
|
406
|
+
return true;
|
|
322
407
|
}
|
|
323
|
-
|
|
408
|
+
catch {
|
|
409
|
+
return false;
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
/**
|
|
413
|
+
* AppKit's execution context once it exists, or `undefined`.
|
|
414
|
+
*
|
|
415
|
+
* Lazily imported (and `@vite-ignore`d) because `@databricks/appkit` is an
|
|
416
|
+
* OPTIONAL peer this module must never make required. The import is only
|
|
417
|
+
* attempted once {@link appKitInstalled} says there is something to import, and a
|
|
418
|
+
* failure resolves to `undefined` rather than rejecting - a missing peer is the
|
|
419
|
+
* expected path, not an error.
|
|
420
|
+
*
|
|
421
|
+
* `getExecutionContext()` THROWS until AppKit has booted, so the call is caught
|
|
422
|
+
* and only a real context is reported. The module handle is memoized; the
|
|
423
|
+
* context lookup is not, so a call before boot answers "not yet" and a later one
|
|
424
|
+
* still sees the context.
|
|
425
|
+
*/
|
|
426
|
+
const appKitModule = functionModule.memoize(async () => {
|
|
427
|
+
if (!appKitInstalled())
|
|
428
|
+
return undefined;
|
|
429
|
+
const specifier = APPKIT_MODULE;
|
|
430
|
+
return (await import(__rewriteRelativeImportExtension(/* @vite-ignore */ specifier)).catch(() => undefined));
|
|
431
|
+
});
|
|
432
|
+
/**
|
|
433
|
+
* Latch {@link appKitContext} once AppKit's execution context exists.
|
|
434
|
+
*
|
|
435
|
+
* Fire-and-forget, because the caller is a SYNCHRONOUS lookup and the check
|
|
436
|
+
* needs a lazy import. The affirmative is all that is stored: AppKit's context
|
|
437
|
+
* does not exist until it boots, and `getExecutionContext()` throws until then,
|
|
438
|
+
* so remembering a negative would permanently disable the bundle for a process
|
|
439
|
+
* that is seconds away from having one. Every call before the latch closes
|
|
440
|
+
* re-attempts, which is what makes "not available yet" retry rather than stick.
|
|
441
|
+
*/
|
|
442
|
+
function confirmAppKitContext() {
|
|
443
|
+
void appKitModule()
|
|
444
|
+
.then((appkit) => {
|
|
445
|
+
if (!appkit)
|
|
446
|
+
return;
|
|
447
|
+
try {
|
|
448
|
+
if (appkit.getExecutionContext()?.client)
|
|
449
|
+
appKitContext = true;
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
// AppKit has not booted yet; a later call re-checks.
|
|
453
|
+
}
|
|
454
|
+
})
|
|
455
|
+
.catch(() => undefined);
|
|
324
456
|
}
|
|
325
457
|
/** A non-empty bundle value with every `${...}` interpolation resolved. */
|
|
326
458
|
function resolvedString(value) {
|
|
@@ -357,10 +489,8 @@ function read(source, cwd) {
|
|
|
357
489
|
break;
|
|
358
490
|
case "bundle": {
|
|
359
491
|
const bundle = bundleFile(cwd);
|
|
360
|
-
if (bundle)
|
|
492
|
+
if (bundle)
|
|
361
493
|
yield bundleApp(bundle.data);
|
|
362
|
-
yield bundleVariables(bundle.data);
|
|
363
|
-
}
|
|
364
494
|
break;
|
|
365
495
|
}
|
|
366
496
|
}
|
|
@@ -442,4 +572,4 @@ function loadBundleFile(cwd, profile) {
|
|
|
442
572
|
}
|
|
443
573
|
return { path, data };
|
|
444
574
|
}
|
|
445
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQ3ZDLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLElBQUksWUFBWSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUYsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztBQUN4QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxJQUFJLElBQUksa0JBQWtCLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFMUQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztBQWlDcEMsTUFBTSxhQUFhLEdBQUcsV0FBVyxDQUFDO0FBQ2xDLE1BQU0sZUFBZSxHQUE0QixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDN0UsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLGdCQUFnQixFQUFFLGlCQUFpQixDQUFVLENBQUM7QUFDekUsTUFBTSxnQkFBZ0IsR0FBRyxNQUFNLENBQUM7QUFDaEMsTUFBTSxxQkFBcUIsR0FBRztJQUM1QixVQUFVLEVBQUUsQ0FBQyxNQUFNLENBQUM7SUFDcEIsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDO0NB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QyxDQUFDO1FBQ3pGLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZGLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDeEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFDRCxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExheWVyZWQgY29uZmlndXJhdGlvbiBsb29rdXA6IGVudmlyb25tZW50LCBgLmVudmAsIERhdGFicmlja3MgYnVuZGxlLlxuICpcbiAqIEV2ZXJ5IHBhY2thZ2UgcmVzb2x2ZXMgc2V0dGluZ3MgdGhlIHNhbWUgd2F5OiB0YWtlIHRoZSBjYWxsZXIncyB2YWx1ZSwgZWxzZVxuICogYW4gZW52aXJvbm1lbnQgdmFyaWFibGUsIGVsc2UgYSBkZWZhdWx0LiBMb2NhbCBkZXZlbG9wbWVudCBhZGRzIHR3byBmYWxsYmFja1xuICogbG9jYXRpb25zOiBgLmVudmAgZmlsZXMgYW5kIGByZXNvdXJjZXMuYXBwcy48YXBwPi5jb25maWcuZW52YCBvciByb290XG4gKiBgdmFyaWFibGVzYCBpbiBgZGF0YWJyaWNrcy55bWxgLlxuICpcbiAqIFR3byB0aGluZ3MgbWFrZSBpdCBjaGVhcCB0byBjYWxsIGZyb20gYSBob3QgcGF0aDpcbiAqXG4gKiAgIC0ge0BsaW5rIHZhbHVlc30gaXMgTEFaWSAoYW4gYG9iamVjdC5TZXF1ZW5jZWApLCBzbyBgZGF0YWJyaWNrcyBidW5kbGVcbiAqICAgICB2YWxpZGF0ZWAgaXMgb25seSBzcGF3bmVkIHdoZW4gdGhlIGVudmlyb25tZW50IGFuZCBgLmVudmAgYm90aCBtaXNzZWQuXG4gKiAgIC0gdGhlIHBhcnNlZCBgLmVudmAgYW5kIGJ1bmRsZSBhcmUgY2FjaGVkIHRocm91Z2gge0BsaW5rIGNvbnRleHQuY2FjaGVkfSwgc29cbiAqICAgICB0aGUgc3Bhd24gaGFwcGVucyBvbmNlIHBlciB3b3JraW5nIGRpcmVjdG9yeSBhbmQgYSBgY3dkYCBjaGFuZ2UgbWlzc2VzXG4gKiAgICAgcmF0aGVyIHRoYW4gcmV0dXJuaW5nIGFub3RoZXIgcHJvamVjdCdzIGNvbmZpZy5cbiAqXG4gKiBJbnNpZGUgYSBkZXBsb3llZCBEYXRhYnJpY2tzIEFwcCBib3RoIGZpbGUgc291cmNlcyBhcmUgc2tpcHBlZCBieSBkZWZhdWx0XG4gKiAoe0BsaW5rIGlzRGF0YWJyaWNrc0FwcEVudn0pOiB0aGUgcGxhdGZvcm0gaGFzIGFscmVhZHkgdHVybmVkIHRoZW0gaW50byByZWFsXG4gKiBlbnZpcm9ubWVudCB2YXJpYWJsZXMsIHRoZXJlIGlzIG5vIGJ1bmRsZSB0byB2YWxpZGF0ZSwgYW5kIHRoZSBgZGF0YWJyaWNrc2BcbiAqIENMSSBpcyBub3Qgb24gdGhlIGltYWdlLiBCb29sZWFuIGVudmlyb25tZW50IG92ZXJyaWRlcyBjYW4gZm9yY2UgZWl0aGVyIGZpbGVcbiAqIHNvdXJjZSBvbiBvciBvZmYgd2hlbiBhIHRvb2wgbmVlZHMgZGlmZmVyZW50IGJlaGF2aW9yLlxuICpcbiAqIE5vZGUtb25seSAoYGNoaWxkX3Byb2Nlc3NgLCBgZnNgLCBgcHJvY2Vzc2ApLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBzcGF3blN5bmMgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyByZWFkRmlsZVN5bmMgfSBmcm9tIFwibm9kZTpmc1wiO1xuaW1wb3J0IHsgZGlybmFtZSwgaXNBYnNvbHV0ZSwgcmVsYXRpdmUsIHJlc29sdmUsIHNlcCB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IHBhcnNlRW52IH0gZnJvbSBcIm5vZGU6dXRpbFwiO1xuaW1wb3J0IHsgY29udGV4dCwganNvbiwgbG9nLCBvYmplY3QsIHN0cmluZyBhcyBzdHJpbmdNb2R1bGUgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IHN0YXRTeW5jIH0gZnJvbSBcIi4vZmlsZS50c1wiO1xuaW1wb3J0IHsgcm9vdCBhcyByZXNvbHZlUHJvamVjdFJvb3QgfSBmcm9tIFwiLi9wcm9qZWN0LnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJjb25maWdcIik7XG5cbmV4cG9ydCB0eXBlIENvbmZpZ0tleSA9IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4vKiogV2hlcmUgYSB2YWx1ZSBtYXkgY29tZSBmcm9tLCBjb25zdWx0ZWQgaW4gdGhlIG9yZGVyIGdpdmVuLiAqL1xuZXhwb3J0IHR5cGUgQ29uZmlnU291cmNlID0gXCJlbnZcIiB8IFwiZG90ZW52XCIgfCBcImJ1bmRsZVwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZ09wdGlvbnMge1xuICAvKipcbiAgICogT3V0ZXJtb3N0IG5hbWVzcGFjZXMgdHJpZWQgYmVmb3JlIGVhY2gga2V5LiBEZWZhdWx0cyB0byBgREJYX1RPT0xTYC5cbiAgICovXG4gIHNjb3BlPzogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKiBDYXBhYmlsaXR5IG5hbWVzcGFjZXMgaW5zZXJ0ZWQgYWZ0ZXIgdGhlIHNjb3BlIGFuZCBiZWZvcmUgZWFjaCBrZXkuICovXG4gIHByZWZpeD86IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAvKiogRGlyZWN0b3J5IHRvIHJlc29sdmUgYC5lbnZgIGFuZCB0aGUgYnVuZGxlIGZyb20uIERlZmF1bHQ6IGBwcm9jZXNzLmN3ZCgpYC4gKi9cbiAgY3dkPzogc3RyaW5nO1xuICAvKiogU291cmNlcyBpbiBwcmVjZWRlbmNlIG9yZGVyLiBEZWZhdWx0OiBgZW52YCwgYGRvdGVudmAsIGBidW5kbGVgLiAqL1xuICBzb3VyY2VzPzogQ29uZmlnU291cmNlIHwgcmVhZG9ubHkgQ29uZmlnU291cmNlW107XG59XG5cbi8qKiBPbmUgcmVzb2x2ZWQgdmFsdWUsIHRhZ2dlZCB3aXRoIHRoZSBrZXkgYW5kIHNvdXJjZSBpdCBjYW1lIGZyb20uICovXG5pbnRlcmZhY2UgQ29uZmlnVmFsdWUge1xuICBrZXk6IHN0cmluZztcbiAgc291cmNlOiBDb25maWdTb3VyY2U7XG4gIHZhbHVlOiBzdHJpbmc7XG59XG5cbi8qKiBBIGNvbmZpZyBmaWxlIGZvdW5kIG9uIGRpc2ssIHdpdGggaXRzIHBhcnNlZCBjb250ZW50cy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ29uZmlnRmlsZSB7XG4gIHBhdGg6IHN0cmluZztcbiAgZGF0YTogUmVjb3JkPHN0cmluZywgdW5rbm93bj47XG59XG5cbmNvbnN0IERFRkFVTFRfU0NPUEUgPSBcIkRCWF9UT09MU1wiO1xuY29uc3QgREVGQVVMVF9TT1VSQ0VTOiByZWFkb25seSBDb25maWdTb3VyY2VbXSA9IFtcImVudlwiLCBcImRvdGVudlwiLCBcImJ1bmRsZVwiXTtcbmNvbnN0IEJVTkRMRV9GSUxFX05BTUVTID0gW1wiZGF0YWJyaWNrcy55bWxcIiwgXCJkYXRhYnJpY2tzLnlhbWxcIl0gYXMgY29uc3Q7XG5jb25zdCBET1RFTlZfRklMRV9OQU1FID0gXCIuZW52XCI7XG5jb25zdCBOT0RFX0VOVl9BTFRFUk5BVElWRVMgPSB7XG4gIHByb2R1Y3Rpb246IFtcInByb2RcIl0sXG4gIGRldmVsb3BtZW50OiBbXCJkZXZcIl0sXG59IGFzIGNvbnN0IHNhdGlzZmllcyBSZWNvcmQ8c3RyaW5nLCByZWFkb25seSBzdHJpbmdbXT47XG5cbi8qKiBIaWdoZXN0IHZhbGlkIFRDUCBwb3J0IG51bWJlci4gKi9cbmV4cG9ydCBjb25zdCBNQVhfVENQX1BPUlQgPSA2NV81MzU7XG5cbi8qKiBCb29sZWFuIGVudmlyb25tZW50IG92ZXJyaWRlIGZvciB7QGxpbmsgaXNEYXRhYnJpY2tzQXBwRW52fS4gKi9cbmV4cG9ydCBjb25zdCBEQVRBQlJJQ0tTX0FQUF9FTlZfS0VZID0gXCJEQlhfVE9PTFNfREFUQUJSSUNLU19BUFBfRU5WXCI7XG5cbi8qKiBCb29sZWFuIGVudmlyb25tZW50IG92ZXJyaWRlIGZvciBwcm9qZWN0IGAuZW52YCByZWFkcy4gKi9cbmV4cG9ydCBjb25zdCBDT05GSUdfRE9URU5WX0tFWSA9IFwiREJYX1RPT0xTX0NPTkZJR19ET1RFTlZcIjtcblxuLyoqIEJvb2xlYW4gZW52aXJvbm1lbnQgb3ZlcnJpZGUgZm9yIERhdGFicmlja3MgYnVuZGxlIHJlYWRzLiAqL1xuZXhwb3J0IGNvbnN0IENPTkZJR19CVU5ETEVfS0VZID0gXCJEQlhfVE9PTFNfQ09ORklHX0JVTkRMRVwiO1xuXG4vKiogRXhhY3QgcHJvY2Vzcy1lbnZpcm9ubWVudCBsb29rdXAgZm9yIGNhbGxlcnMgdGhhdCBkbyBub3QgcmVhZCBsb2NhbCBjb25maWcgZmlsZXMuICovXG5leHBvcnQgY29uc3QgRU5WX09OTFkgPSB7IHNjb3BlOiBbXSBhcyBjb25zdCwgc291cmNlczogXCJlbnZcIiBhcyBjb25zdCB9O1xuXG5leHBvcnQgY29uc3QgYnVuZGxlVmFsdWUgPSB6XG4gIC5zdHJpbmcoKVxuICAudHJhbnNmb3JtKCh2YWx1ZTogc3RyaW5nKSA9PiB2YWx1ZS50cmltKCkpXG4gIC5yZWZpbmUoKHZhbHVlOiBzdHJpbmcpID0+IHZhbHVlLmxlbmd0aCA+IDApXG4gIC5yZWZpbmUoKHZhbHVlOiBzdHJpbmcpID0+ICEvXFwkXFx7W159XStcXH0vLnRlc3QodmFsdWUpLCB7XG4gICAgbWVzc2FnZTogXCJJbnRlcnBvbGF0ZWQgdmFsdWVzIGFyZSBub3QgYWxsb3dlZFwiLFxuICB9KTtcblxuLyoqXG4gKiBUaGUgR0VORVJJQyBzaGFwZSBvZiBhIGJ1bmRsZSByZXNvdXJjZTogYSBuYW1lLCBhbmQgd2hhdGV2ZXIgZWxzZSB0aGUgcmVzb3VyY2VcbiAqIHR5cGUgY2Fycmllcy4gRGVsaWJlcmF0ZWx5IHVub3BpbmlvbmF0ZWQgYW5kIGBwYXNzdGhyb3VnaCgpYCAtIHRoZSBjb25jcmV0ZVxuICogcmVzb3VyY2Uga2luZHMgKGBzcWxfd2FyZWhvdXNlYCwgYGdlbmllX3NwYWNlYCwgYHBvc3RncmVzYCwgLi4uKSBhcmVcbiAqIERhdGFicmlja3MtQXBwIGNvbmNlcHRzIHRoYXQgYmVsb25nIHRvIHRoZSBwYWNrYWdlIHRoYXQgcmVzb2x2ZXMgdGhlbSwgc29cbiAqIG5vZGUtYXBwa2l0IGAuZXh0ZW5kKClgcyB0aGlzIHJhdGhlciB0aGFuIHRoaXMgbW9kdWxlIGtub3dpbmcgYWJvdXQgdGhlbS5cbiAqL1xuZXhwb3J0IGNvbnN0IGJ1bmRsZVJlc291cmNlU2NoZW1hID0gei5vYmplY3QoeyBuYW1lOiBidW5kbGVWYWx1ZS5vcHRpb25hbCgpIH0pLnBhc3N0aHJvdWdoKCk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVFbnZFbnRyeVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgbmFtZTogYnVuZGxlVmFsdWUub3B0aW9uYWwoKSxcbiAgdmFsdWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgdmFsdWVfZnJvbTogYnVuZGxlVmFsdWUub3B0aW9uYWwoKSxcbn0pO1xuXG5jb25zdCBidW5kbGVWYXJpYWJsZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgZGVmYXVsdDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB2YWx1ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVBcHBTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IGJ1bmRsZVZhbHVlLm9wdGlvbmFsKCksXG4gIHNvdXJjZV9jb2RlX3BhdGg6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgY29uZmlnOiB6Lm9iamVjdCh7IGVudjogei5hcnJheShidW5kbGVFbnZFbnRyeVNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxuICByZXNvdXJjZXM6IHouYXJyYXkoYnVuZGxlUmVzb3VyY2VTY2hlbWEpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgYnVuZGxlQXBwc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgcmVzb3VyY2VzOiB6Lm9iamVjdCh7IGFwcHM6IHoucmVjb3JkKHouc3RyaW5nKCksIGJ1bmRsZUFwcFNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxufSk7XG5cbmNvbnN0IGJ1bmRsZVZhcmlhYmxlc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgdmFyaWFibGVzOiB6LnJlY29yZCh6LnN0cmluZygpLCBidW5kbGVWYXJpYWJsZVNjaGVtYSkub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbiAqIERldGVjdCBhIERhdGFicmlja3MgQXBwIHJ1bnRpbWUgZnJvbSBpdHMgcmVxdWlyZWQgbmFtZSwgaG9zdCwgYW5kIHBvcnQuXG4gKlxuICogYERCWF9UT09MU19EQVRBQlJJQ0tTX0FQUF9FTlZgIHRha2VzIHByZWNlZGVuY2Ugd2hlbiBpdCBjb250YWlucyBhIHJlY29nbml6ZWRcbiAqIGJvb2xlYW4gdmFsdWUuIFRoaXMgbGV0cyBsb2NhbCB0b29scyBlbXVsYXRlIHRoZSBkZXBsb3llZCBydW50aW1lIChgdHJ1ZWApIG9yXG4gKiBsZXRzIHVudXN1YWwgZGVwbG95ZWQgcHJvY2Vzc2VzIHJldGFpbiBsb2NhbCBjb25maWcgbG9va3VwIChgZmFsc2VgKS4gQW5cbiAqIGFic2VudCBvciB1bnJlY29nbml6ZWQgb3ZlcnJpZGUgZmFsbHMgYmFjayB0byBzdHJ1Y3R1cmFsIGRldGVjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRGF0YWJyaWNrc0FwcEVudihcbiAgc291cmNlOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+ID0gcHJvY2Vzcy5lbnYsXG4pOiBib29sZWFuIHtcbiAgY29uc3Qgb3ZlcnJpZGUgPSBvYmplY3QudG9Cb29sZWFuKHNvdXJjZVtEQVRBQlJJQ0tTX0FQUF9FTlZfS0VZXSk7XG4gIGlmIChvdmVycmlkZSAhPT0gdW5kZWZpbmVkKSByZXR1cm4gb3ZlcnJpZGU7XG4gIGNvbnN0IGFwcE5hbWUgPSBzb3VyY2UuREFUQUJSSUNLU19BUFBfTkFNRT8udHJpbSgpO1xuICBjb25zdCBob3N0ID0gc291cmNlLkRBVEFCUklDS1NfSE9TVD8udHJpbSgpO1xuICBjb25zdCBwb3J0ID0gc291cmNlLkRBVEFCUklDS1NfQVBQX1BPUlQ/LnRyaW0oKTtcbiAgaWYgKCFhcHBOYW1lIHx8ICFob3N0IHx8ICFwb3J0KSByZXR1cm4gZmFsc2U7XG4gIHRyeSB7XG4gICAgaWYgKCFbXCJodHRwOlwiLCBcImh0dHBzOlwiXS5pbmNsdWRlcyhuZXcgVVJMKGhvc3QpLnByb3RvY29sKSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgcG9ydE51bWJlciA9IG9iamVjdC50b051bWJlcihwb3J0KTtcbiAgcmV0dXJuIChcbiAgICBwb3J0TnVtYmVyICE9PSB1bmRlZmluZWQgJiZcbiAgICBOdW1iZXIuaXNJbnRlZ2VyKHBvcnROdW1iZXIpICYmXG4gICAgcG9ydE51bWJlciA+PSAxICYmXG4gICAgcG9ydE51bWJlciA8PSBNQVhfVENQX1BPUlRcbiAgKTtcbn1cblxuLyoqIENhbmRpZGF0ZSBuYW1lcyBpbiBzY29wZSwgcHJlZml4LCBhbmQgaW5wdXQgcHJlY2VkZW5jZSBvcmRlci4gKi9cbmZ1bmN0aW9uIGtleXMoaW5wdXQ6IENvbmZpZ0tleSwgb3B0aW9uczogUGljazxDb25maWdPcHRpb25zLCBcInNjb3BlXCIgfCBcInByZWZpeFwiPiA9IHt9KTogc3RyaW5nW10ge1xuICBjb25zdCBzY29wZXMgPSBvYmplY3Quc2VxdWVuY2Uob3B0aW9ucy5zY29wZSA/PyBERUZBVUxUX1NDT1BFKS50b0FycmF5KCk7XG4gIGNvbnN0IHByZWZpeGVzID0gb3B0aW9ucy5wcmVmaXggPT09IHVuZGVmaW5lZCA/IFtdIDogb2JqZWN0LnNlcXVlbmNlKG9wdGlvbnMucHJlZml4KS50b0FycmF5KCk7XG4gIHJldHVybiBbXG4gICAgLi4ub2JqZWN0XG4gICAgICAuc2VxdWVuY2UoaW5wdXQpXG4gICAgICAuZmxhdE1hcCgoa2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHByZWZpeGVkID0gcHJlZml4ZXMubGVuZ3RoID4gMCA/IHByZWZpeGVzLm1hcCgocHJlZml4KSA9PiBqb2luKHByZWZpeCwga2V5KSkgOiBba2V5XTtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAuLi5zY29wZXMuZmxhdE1hcCgoc2NvcGUpID0+IHByZWZpeGVkLm1hcCgoa2V5KSA9PiBqb2luKHNjb3BlLCBrZXkpKSksXG4gICAgICAgICAgLi4ucHJlZml4ZWQsXG4gICAgICAgICAga2V5LFxuICAgICAgICBdO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5Lmxlbmd0aCA+IDApXG4gICAgICAuZGlzdGluY3QoKSxcbiAgXTtcbn1cblxuLyoqXG4gKiBFdmVyeSB2YWx1ZSB0aGF0IHJlc29sdmVzIGZvciBgaW5wdXRgLCBpbiBzb3VyY2UtdGhlbi1rZXkgcHJlY2VkZW5jZSBvcmRlcixcbiAqIGFzIGEgTEFaWSBzZXF1ZW5jZTogbm90aGluZyBwYXN0IHRoZSBmaXJzdCBjb25zdW1lZCBlbGVtZW50IGlzIHJlYWQsIHNvXG4gKiBgdmFsdWVzKGtleSkuZmlyc3QoKWAgbmV2ZXIgc3Bhd25zIHRoZSBEYXRhYnJpY2tzIENMSSB3aGVuIHRoZSBlbnZpcm9ubWVudFxuICogYWxyZWFkeSBhbnN3ZXJlZC5cbiAqXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBDb25maWdPcHRpb25zID0ge30pOiBvYmplY3QuU2VxdWVuY2U8Q29uZmlnVmFsdWU+IHtcbiAgY29uc3QgY2FuZGlkYXRlcyA9IGtleXMoaW5wdXQsIG9wdGlvbnMpO1xuICBjb25zdCBzb3VyY2VzID0gb2JqZWN0LnNlcXVlbmNlPENvbmZpZ1NvdXJjZT4ob3B0aW9ucy5zb3VyY2VzID8/IERFRkFVTFRfU09VUkNFUyk7XG4gIHJldHVybiBvYmplY3Quc2VxdWVuY2Uoe1xuICAgICpbU3ltYm9sLml0ZXJhdG9yXSgpOiBHZW5lcmF0b3I8Q29uZmlnVmFsdWU+IHtcbiAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBtYXAgb2YgcmVhZChzb3VyY2UsIG9wdGlvbnMuY3dkKSkge1xuICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwobWFwW2tleV0pO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB5aWVsZCB7IGtleSwgc291cmNlLCB2YWx1ZSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIFRoZSBmaXJzdCB2YWx1ZSB0aGF0IHJlc29sdmVzIGZvciBgaW5wdXRgLCBvciBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZG9tYWluID0gY29uZmlnLnRleHQoW1wiVFVOTkVMX1BVQkxJQ19ET01BSU5cIiwgXCJQVUJMSUNfRE9NQUlOXCJdKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRleHQoaW5wdXQ6IENvbmZpZ0tleSwgb3B0aW9uczogQ29uZmlnT3B0aW9ucyA9IHt9KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlcyhpbnB1dCwgb3B0aW9ucykuYXQoMCk/LnZhbHVlO1xufVxuXG4vKipcbiAqIFRoZSBQUklNQVJZIChmdWxseS1zY29wZWQpIG5hbWUgZm9yIGBpbnB1dGAgLSB3aGF0IHRvIHByaW50IGluIGEgbG9nIGxpbmUgb3IgYW5cbiAqIGVycm9yLCBzbyB0aGUgbWVzc2FnZSBuYW1lcyB0aGUgdmFyaWFibGUgYSByZWFkZXIgc2hvdWxkIHNldC4gRG8gbm90IGluZGV4XG4gKiBga2V5cyguLi4pWzBdYCBmb3IgdGhpcyBpZiBgaW5wdXRgIG1heSBiZSBhIGJhcmUgc3RyaW5nLlxuICpcbiAqIEBleGFtcGxlXG4gKiBsb2dnZXIud2FybihgJHtjb25maWcubmFtZShKV1RfU0VDUkVUX0VOVil9IGlzIG5vdCBzZXRgKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hbWUoXG4gIGlucHV0OiBDb25maWdLZXksXG4gIG9wdGlvbnM6IFBpY2s8Q29uZmlnT3B0aW9ucywgXCJzY29wZVwiIHwgXCJwcmVmaXhcIj4gPSB7fSxcbik6IHN0cmluZyB7XG4gIHJldHVybiBrZXlzKGlucHV0LCBvcHRpb25zKVswXSA/PyBcIlwiO1xufVxuXG4vKipcbiAqIFNhZmUgYC5lbnYuPG5hbWU+YCBzdWZmaXhlcyBmb3IgYSBOb2RlIGVudmlyb25tZW50LCBleGFjdCBzcGVsbGluZyBmaXJzdC5cbiAqIEtub3duIGxvbmcgYW5kIHNob3J0IG5hbWVzIGFyZSBpbnRlcmNoYW5nZWFibGU7IHVua25vd24gbmFtZXMgcGFzcyB0aHJvdWdoLlxuICovXG5mdW5jdGlvbiBub2RlRW52TmFtZXMobm9kZUVudjogdW5rbm93bik6IHN0cmluZ1tdIHtcbiAgY29uc3QgbmFtZSA9IHN0cmluZ01vZHVsZS50cmltVG9OdWxsKG5vZGVFbnYpPy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIW5hbWUgfHwgIS9eW2EtejAtOV8tXSskLy50ZXN0KG5hbWUpKSByZXR1cm4gW107XG4gIGZvciAoY29uc3QgW2Nhbm9uaWNhbCwgYWx0ZXJuYXRpdmVzXSBvZiBPYmplY3QuZW50cmllcyhOT0RFX0VOVl9BTFRFUk5BVElWRVMpKSB7XG4gICAgY29uc3QgbmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdID0gYWx0ZXJuYXRpdmVzO1xuICAgIGlmIChuYW1lID09PSBjYW5vbmljYWwgfHwgbmFtZXMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgIHJldHVybiBbLi4ub2JqZWN0LnNlcXVlbmNlKG5hbWUsIGNhbm9uaWNhbCwgYWx0ZXJuYXRpdmVzKS5kaXN0aW5jdCgpXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFtuYW1lXTtcbn1cblxuZnVuY3Rpb24gam9pbiguLi5wYXJ0czogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gcGFydHNcbiAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LnRyaW0oKSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmpvaW4oXCJfXCIpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBzdHJpbmc6IGBjb25maWd1cmVkYCB3aGVuIG5vbi1lbXB0eSwgZWxzZSB7QGxpbmsgdGV4dH0sIGVsc2UgYHVuZGVmaW5lZGAuXG4gKlxuICogVGhlIGNvZXJjaW9uIHJ1bGVzIGFyZSBkZWxpYmVyYXRlbHkgbG9vc2UgKGBvbmAgLyBgeWVzYCAvIGAxYCBhcmUgYWxsXG4gKiBgdHJ1ZWApIGJlY2F1c2UgdmFsdWVzIG1heSBjb21lIGZyb20gYSBmaWxlIGEgaHVtYW4gdHlwZWQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbmZpZy5zdHJpbmcob3B0aW9ucy5ob3N0LCBcIlNNVFBfSE9TVFwiKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZyhcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwoY29uZmlndXJlZCkgPz8gdGV4dChpbnB1dCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGJvb2xlYW4gdGhyb3VnaCBgb2JqZWN0LnRvQm9vbGVhbmAuIGB1bmRlZmluZWRgIHdoZW4gbmVpdGhlciBzb3VyY2VcbiAqIGlzIGludGVycHJldGFibGUsIHNvIHRoZSBjYWxsZXIgcGlja3MgYSBkZWZhdWx0IHdpdGggYD8/YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJvb2xlYW4oXG4gIGNvbmZpZ3VyZWQ6IHVua25vd24sXG4gIGlucHV0OiBDb25maWdLZXksXG4gIG9wdGlvbnM/OiBDb25maWdPcHRpb25zLFxuKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBvYmplY3QudG9Cb29sZWFuKGNvbmZpZ3VyZWQpID8/IG9iamVjdC50b0Jvb2xlYW4odGV4dChpbnB1dCwgb3B0aW9ucykpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBwb3NpdGl2ZSBudW1iZXIgdGhhdCBtYXkgYmUgZnJhY3Rpb25hbCAoYSBzY29yZSB0aHJlc2hvbGQsIGEgcmF0aW8pLlxuICogVXNlIHtAbGluayBwb3NpdGl2ZUludH0gZm9yIGEgY291bnQsIHBvcnQsIG9yIHRpbWVvdXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb3NpdGl2ZU51bWJlcihcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgZmFsbGJhY2s6IG51bWJlcixcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBudW1iZXIge1xuICByZXR1cm4gdG9Qb3NpdGl2ZU51bWJlcihjb25maWd1cmVkKSA/PyB0b1Bvc2l0aXZlTnVtYmVyKHRleHQoaW5wdXQsIG9wdGlvbnMpKSA/PyBmYWxsYmFjaztcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgcG9zaXRpdmUgaW50ZWdlciAoYSBwb3J0LCBhIHRpbWVvdXQsIGEgcGFnZSBzaXplKSwgZmxvb3JlZC4gQVxuICogbm9uLW51bWVyaWMgb3Igbm9uLXBvc2l0aXZlIHZhbHVlIGlzIHRyZWF0ZWQgYXMgQUJTRU5UIHJhdGhlciB0aGFuIGZhdGFsIC1cbiAqIHRoZXNlIGFyZSBjZWlsaW5ncyB3aGVyZSBhIHNhbmUgZGVmYXVsdCBiZWF0cyBhIGJvb3QgZmFpbHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlSW50KFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBmYWxsYmFjazogbnVtYmVyLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIGNvbnN0IHJlc29sdmVkID0gcG9zaXRpdmVOdW1iZXIoY29uZmlndXJlZCwgaW5wdXQsIGZhbGxiYWNrLCBvcHRpb25zKTtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmVzb2x2ZWQpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBsaXN0IHRocm91Z2ggYHN0cmluZy5wYXJzZUxpc3RgLCBzbyBhbiBhcnJheSBmcm9tIHR5cGVkIGNvbmZpZyBhbmQgYVxuICogYFwiYSwgYiBjXCJgIHN0cmluZyBub3JtYWxpemUgaWRlbnRpY2FsbHkuIGBbXWAgd2hlbiBuZWl0aGVyIHNvdXJjZSBoYXMgZW50cmllcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3QoXG4gIGNvbmZpZ3VyZWQ6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHwgbnVsbCxcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgdHJhbnNmb3JtPzogKGVudHJ5OiBzdHJpbmcpID0+IHN0cmluZyxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZyb21Db25maWcgPSBzdHJpbmdNb2R1bGUucGFyc2VMaXN0KGNvbmZpZ3VyZWQsIHRyYW5zZm9ybSk7XG4gIHJldHVybiBmcm9tQ29uZmlnLmxlbmd0aCA+IDBcbiAgICA/IGZyb21Db25maWdcbiAgICA6IHN0cmluZ01vZHVsZS5wYXJzZUxpc3QodGV4dChpbnB1dCwgb3B0aW9ucyksIHRyYW5zZm9ybSk7XG59XG5cbmZ1bmN0aW9uIHRvUG9zaXRpdmVOdW1iZXIodmFsdWU6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXJzZWQgPSBvYmplY3QudG9OdW1iZXIodmFsdWUpO1xuICByZXR1cm4gcGFyc2VkICE9PSB1bmRlZmluZWQgJiYgcGFyc2VkID4gMCA/IHBhcnNlZCA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGUgRGF0YWJyaWNrcyBidW5kbGUgb3V0cHV0IGZvciBgY3dkYCAtIGBkYXRhYnJpY2tzIGJ1bmRsZSB2YWxpZGF0ZSAtLW91dHB1dFxuICoganNvbmAgcnVuIGZyb20gdGhlIGRpcmVjdG9yeSBob2xkaW5nIGBkYXRhYnJpY2tzLnltbGAsIHdpdGggdGhlIGNvbmZpZyBmaWxlJ3NcbiAqIHBhdGguIEEgbm9uLXplcm8gdmFsaWRhdGlvbiBtYXkgc3RpbGwgcmV0dXJuIHBhcnRpYWwgSlNPTiB3aXRoIHVzYWJsZVxuICogdmFyaWFibGVzLiBgdW5kZWZpbmVkYCB3aGVuIGJ1bmRsZSByZWFkcyBhcmUgZGlzYWJsZWQsIHRoZXJlIGlzIG5vIGJ1bmRsZSwgb3JcbiAqIHRoZSBDTEkgcHJvZHVjZXMgbm8gSlNPTi5cbiAqXG4gKiBDYWNoZWQgb25jZSBwZXIgcmVzb2x2ZWQgd29ya2luZy1kaXJlY3RvcnkgY29udGV4dCBhbmRcbiAqIGBEQVRBQlJJQ0tTX0NPTkZJR19QUk9GSUxFYCB0aHJvdWdoIHtAbGluayBjb250ZXh0LmNhY2hlZH0sIHNvIHJlcGVhdGVkXG4gKiBsb29rdXBzIGRvIG5vdCByZXJ1biB2YWxpZGF0aW9uIGFuZCBjaGFuZ2luZyBlaXRoZXIgY2Fubm90IHJldHVybiBhbm90aGVyXG4gKiBjb250ZXh0J3MgYnVuZGxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVuZGxlRmlsZShjd2Q/OiBzdHJpbmcgfCBudWxsKTogQ29uZmlnRmlsZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHByb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOVj8udHJpbSgpLnRvTG93ZXJDYXNlKCkgPT09IFwicHJvZHVjdGlvblwiO1xuICBpZiAoIWZpbGVTb3VyY2VFbmFibGVkKENPTkZJR19CVU5ETEVfS0VZLCAhcHJvZHVjdGlvbiAmJiAhaXNEYXRhYnJpY2tzQXBwRW52KCkpKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25zdCBwcm9maWxlID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19DT05GSUdfUFJPRklMRSk7XG4gIHJldHVybiBjYWNoZWRDb25maWcoW1wiYnVuZGxlXCIsIHByb2ZpbGUgPz8gXCJcIl0sIGN3ZCwgKHJlc29sdmVkKSA9PlxuICAgIGxvYWRCdW5kbGVGaWxlKHJlc29sdmVkLCBwcm9maWxlKSxcbiAgKTtcbn1cblxuLyoqXG4gKiBUaGUgc2luZ2xlIEFwcCdzIGxpdGVyYWwgYGNvbmZpZy5lbnZgIGVudHJpZXMsIGZsYXR0ZW5lZCB0byBgbmFtZSAtPiB2YWx1ZWAuXG4gKlxuICogQSBgdmFsdWVfZnJvbWAgZW50cnkgbmFtZXMgYSBidW5kbGUgcmVzb3VyY2Ugd2hvc2UgaWQgaXMga25vd24gYWZ0ZXJcbiAqIGRlcGxveW1lbnQsIGFuZCByZWFkaW5nIGl0IG5lZWRzIHRoZSByZXNvdXJjZSB2b2NhYnVsYXJ5IHRoaXMgbW9kdWxlXG4gKiBkZWxpYmVyYXRlbHkgZG9lcyBub3QgaGF2ZSAtIG5vZGUtYXBwa2l0IHJlc29sdmVzIHRob3NlIGFnYWluc3QgaXRzIGV4dGVuZGVkXG4gKiB7QGxpbmsgYnVuZGxlUmVzb3VyY2VTY2hlbWF9LiBBbiBgYXBwc2AgYmxvY2sgd2l0aCBtb3JlIHRoYW4gb25lIGFwcCBpc1xuICogYW1iaWd1b3VzIChub3RoaW5nIGhlcmUgc2F5cyB3aGljaCBhcHAgdGhpcyBwcm9jZXNzIGlzKSwgc28gaXQgeWllbGRzIG5vdGhpbmdcbiAqIHJhdGhlciB0aGFuIGEgZ3Vlc3MuXG4gKi9cbmZ1bmN0aW9uIGJ1bmRsZUFwcChpbnB1dDogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBwYXJzZWQgPSBidW5kbGVBcHBzU2NoZW1hLnNhZmVQYXJzZShpbnB1dCk7XG4gIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiB7fTtcbiAgY29uc3QgYXBwcyA9IHBhcnNlZC5kYXRhLnJlc291cmNlcz8uYXBwcztcbiAgaWYgKCFhcHBzKSByZXR1cm4ge307XG4gIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoYXBwcyk7XG4gIGlmIChuYW1lcy5sZW5ndGggIT09IDEpIHJldHVybiB7fTtcbiAgY29uc3QgZW50cmllcyA9IGFwcHNbbmFtZXNbMF0hXT8uY29uZmlnPy5lbnYgPz8gW107XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBpZiAoIWVudHJ5Lm5hbWUpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHZhbHVlID0gcmVzb2x2ZWRTdHJpbmcoZW50cnkudmFsdWUpO1xuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkgcmVzdWx0W2VudHJ5Lm5hbWVdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBSb290IGJ1bmRsZSB2YXJpYWJsZXMgZmxhdHRlbmVkIHRvIGVudmlyb25tZW50LXN0eWxlIGBOQU1FIC0+IHZhbHVlYCBlbnRyaWVzLlxuICpcbiAqIGBkYXRhYnJpY2tzIGJ1bmRsZSB2YWxpZGF0ZWAgcmVzb2x2ZXMgZWFjaCB2YXJpYWJsZSB0byBgdmFsdWVgOyBgZGVmYXVsdGAgaXNcbiAqIHJldGFpbmVkIGFzIGEgZmFsbGJhY2sgZm9yIHBhcnNlZCBidW5kbGUgZGF0YSB0aGF0IGhhcyBub3QgYmVlbiBmdWxseVxuICogcmVzb2x2ZWQuIE5hbWVzIGFyZSBub3JtYWxpemVkIHNvIGEgYnVuZGxlIHZhcmlhYmxlIHN1Y2ggYXNcbiAqIGB0dW5uZWxfcHVibGljX2RvbWFpbmAgYW5zd2VycyBhIGxvb2t1cCBmb3IgYFRVTk5FTF9QVUJMSUNfRE9NQUlOYC5cbiAqL1xuZnVuY3Rpb24gYnVuZGxlVmFyaWFibGVzKGlucHV0OiB1bmtub3duKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IHBhcnNlZCA9IGJ1bmRsZVZhcmlhYmxlc1NjaGVtYS5zYWZlUGFyc2UoaW5wdXQpO1xuICBpZiAoIXBhcnNlZC5zdWNjZXNzKSByZXR1cm4ge307XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtuYW1lLCB2YXJpYWJsZV0gb2YgT2JqZWN0LmVudHJpZXMocGFyc2VkLmRhdGEudmFyaWFibGVzID8/IHt9KSkge1xuICAgIGNvbnN0IGtleSA9IFsuLi5zdHJpbmdNb2R1bGUudG9rZW5pemUobmFtZSldLmpvaW4oXCJfXCIpLnRvVXBwZXJDYXNlKCk7XG4gICAgY29uc3QgdmFsdWUgPSByZXNvbHZlZFN0cmluZyh2YXJpYWJsZS52YWx1ZSkgPz8gcmVzb2x2ZWRTdHJpbmcodmFyaWFibGUuZGVmYXVsdCk7XG4gICAgaWYgKGtleSAmJiB2YWx1ZSAhPT0gbnVsbCkgcmVzdWx0W2tleV0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKiogQSBub24tZW1wdHkgYnVuZGxlIHZhbHVlIHdpdGggZXZlcnkgYCR7Li4ufWAgaW50ZXJwb2xhdGlvbiByZXNvbHZlZC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVkU3RyaW5nKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHBhcnNlZCA9IGJ1bmRsZVZhbHVlLnNhZmVQYXJzZSh2YWx1ZSk7XG4gIHJldHVybiBwYXJzZWQuc3VjY2VzcyA/IHBhcnNlZC5kYXRhIDogbnVsbDtcbn1cblxuLyoqIFBhcnNlZCBgLmVudmAgZm9yIGBjd2RgLCBvciBge31gLiBSZWFkIG9uY2UgcGVyIHJlc29sdmVkIGNvbnRleHQuICovXG5mdW5jdGlvbiBkb3RlbnYoY3dkPzogc3RyaW5nIHwgbnVsbCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBpZiAoIWZpbGVTb3VyY2VFbmFibGVkKENPTkZJR19ET1RFTlZfS0VZKSkgcmV0dXJuIHt9O1xuICBjb25zdCBlbnZpcm9ubWVudHMgPSBub2RlRW52TmFtZXMocHJvY2Vzcy5lbnYuTk9ERV9FTlYpO1xuICByZXR1cm4gY2FjaGVkQ29uZmlnKFtcImRvdGVudlwiLCAuLi5lbnZpcm9ubWVudHNdLCBjd2QsIChyZXNvbHZlZCkgPT5cbiAgICBsb2FkRG90ZW52KHJlc29sdmVkLCBlbnZpcm9ubWVudHMpLFxuICApO1xufVxuXG4vKiogQ2FjaGUgZXZlcnkgdGFyZ2V0IGRpcmVjdG9yeSBzZXBhcmF0ZWx5IHdpdGhpbiB0aGUgYWN0aXZlIHByb2Nlc3MgY29udGV4dC4gKi9cbmZ1bmN0aW9uIGNhY2hlZENvbmZpZzxUPihcbiAgbmFtZTogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGN3ZDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgbG9hZGVyOiAocmVzb2x2ZWQ6IHN0cmluZykgPT4gVCxcbik6IFQge1xuICBjb25zdCBhY3RpdmUgPSBjb250ZXh0LmdldENvbnRleHQoKSA/PyBcIlwiO1xuICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmUoY3dkID8/IFwiLlwiKTtcbiAgcmV0dXJuIGNvbnRleHQuY2FjaGVkKFtcImNvbmZpZ1wiLCBhY3RpdmUsIHJlc29sdmVkLCAuLi5uYW1lXSwgKCkgPT4gbG9hZGVyKHJlc29sdmVkKSk7XG59XG5cbi8qKlxuICogTWFwcyBmb3Igb25lIHNvdXJjZSBpbiBwcmVjZWRlbmNlIG9yZGVyLiBCdW5kbGUgQXBwIGNvbmZpZyBhbmQgcm9vdCB2YXJpYWJsZXNcbiAqIHN0YXkgc2VwYXJhdGUgc28gYSBmaXJzdC1tYXRjaCBsb29rdXAgZG9lcyBub3QgcGFyc2UgdmFyaWFibGVzIGFmdGVyIGFuIEFwcFxuICogdmFsdWUgcmVzb2x2ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlYWQoXG4gIHNvdXJjZTogQ29uZmlnU291cmNlLFxuICBjd2Q/OiBzdHJpbmcsXG4pOiBvYmplY3QuU2VxdWVuY2U8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPj4ge1xuICByZXR1cm4gb2JqZWN0LnNlcXVlbmNlKHtcbiAgICAqW1N5bWJvbC5pdGVyYXRvcl0oKTogR2VuZXJhdG9yPFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4+IHtcbiAgICAgIHN3aXRjaCAoc291cmNlKSB7XG4gICAgICAgIGNhc2UgXCJlbnZcIjpcbiAgICAgICAgICB5aWVsZCBwcm9jZXNzLmVudjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImRvdGVudlwiOlxuICAgICAgICAgIHlpZWxkIGRvdGVudihjd2QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiYnVuZGxlXCI6IHtcbiAgICAgICAgICBjb25zdCBidW5kbGUgPSBidW5kbGVGaWxlKGN3ZCk7XG4gICAgICAgICAgaWYgKGJ1bmRsZSkge1xuICAgICAgICAgICAgeWllbGQgYnVuZGxlQXBwKGJ1bmRsZS5kYXRhKTtcbiAgICAgICAgICAgIHlpZWxkIGJ1bmRsZVZhcmlhYmxlcyhidW5kbGUuZGF0YSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogTG9jYXRlIGBuYW1lc2AgZnJvbSBgY3dkYCBvdXR3YXJkLiBgY3dkYCBpdHNlbGYgaXMgY2hlY2tlZCBiZWZvcmUgdGhlXG4gKiBkaXNjb3ZlcmVkIHByb2plY3Qgcm9vdHMgc28gYSBwYWNrYWdlLWxvY2FsIGZpbGUgd2lucyBvdmVyIHRoZSB3b3Jrc3BhY2Uncy5cbiAqL1xuZnVuY3Rpb24gZmluZENvbmZpZ0ZpbGUoY3dkOiBzdHJpbmcsIG5hbWVzOiByZWFkb25seSBzdHJpbmdbXSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHN0YXJ0ID0gcmVzb2x2ZShjd2QpO1xuICBjb25zdCByb290ID0gcmVzb2x2ZVByb2plY3RSb290KHN0YXJ0KTtcbiAgY29uc3QgcGF0aEZyb21Sb290ID0gcm9vdCA/IHJlbGF0aXZlKHJvb3QsIHN0YXJ0KSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgYm91bmRhcnkgPVxuICAgIHJvb3QgJiZcbiAgICBwYXRoRnJvbVJvb3QgIT09IHVuZGVmaW5lZCAmJlxuICAgICFpc0Fic29sdXRlKHBhdGhGcm9tUm9vdCkgJiZcbiAgICBwYXRoRnJvbVJvb3QgIT09IFwiLi5cIiAmJlxuICAgICFwYXRoRnJvbVJvb3Quc3RhcnRzV2l0aChgLi4ke3NlcH1gKVxuICAgICAgPyByb290XG4gICAgICA6IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgZGlyID0gc3RhcnQ7IDsgZGlyID0gZGlybmFtZShkaXIpKSB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG4gICAgICBjb25zdCBwYXRoID0gcmVzb2x2ZShkaXIsIG5hbWUpO1xuICAgICAgaWYgKHN0YXRTeW5jKHBhdGgpPy5pc0ZpbGUoKSkgcmV0dXJuIHBhdGg7XG4gICAgfVxuICAgIGlmIChib3VuZGFyeSA9PT0gdW5kZWZpbmVkIHx8IGRpciA9PT0gYm91bmRhcnkpIGJyZWFrO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKiBBIHJlY29nbml6ZWQgc291cmNlIG92ZXJyaWRlLCBlbHNlIHRoZSBjYWxsZXIncyBhdXRvbWF0aWMgZGVmYXVsdC4gKi9cbmZ1bmN0aW9uIGZpbGVTb3VyY2VFbmFibGVkKGtleTogc3RyaW5nLCBmYWxsYmFjazogYm9vbGVhbiA9ICFpc0RhdGFicmlja3NBcHBFbnYoKSk6IGJvb2xlYW4ge1xuICByZXR1cm4gb2JqZWN0LnRvQm9vbGVhbihwcm9jZXNzLmVudltrZXldKSA/PyBmYWxsYmFjaztcbn1cblxuZnVuY3Rpb24gbG9hZERvdGVudihcbiAgY3dkOiBzdHJpbmcsXG4gIGVudmlyb25tZW50czogcmVhZG9ubHkgc3RyaW5nW10sXG4pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgY29uc3QgbmFtZXMgPSBbLi4uZW52aXJvbm1lbnRzLm1hcCgobmFtZSkgPT4gYCR7RE9URU5WX0ZJTEVfTkFNRX0uJHtuYW1lfWApLCBET1RFTlZfRklMRV9OQU1FXTtcbiAgY29uc3QgcGF0aCA9IGZpbmRDb25maWdGaWxlKGN3ZCwgbmFtZXMpO1xuICBpZiAoIXBhdGgpIHJldHVybiB7fTtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcGFyc2VFbnYocmVhZEZpbGVTeW5jKHBhdGgsIFwidXRmOFwiKSk7XG4gIH0gY2F0Y2gge1xuICAgIGxvZ2dlci53YXJuKFwiZmFpbGVkIHRvIHJlYWQgZG90ZW52IGZpbGVcIiwgeyBwYXRoIH0pO1xuICAgIHJldHVybiB7fTtcbiAgfVxufVxuXG5mdW5jdGlvbiBsb2FkQnVuZGxlRmlsZShjd2Q6IHN0cmluZywgcHJvZmlsZTogc3RyaW5nIHwgbnVsbCk6IENvbmZpZ0ZpbGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXRoID0gZmluZENvbmZpZ0ZpbGUoY3dkLCBCVU5ETEVfRklMRV9OQU1FUyk7XG4gIGlmICghcGF0aCkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgYXJncyA9IFtcbiAgICBcImJ1bmRsZVwiLFxuICAgIFwidmFsaWRhdGVcIixcbiAgICBcIi0tb3V0cHV0XCIsXG4gICAgXCJqc29uXCIsXG4gICAgLi4uKHByb2ZpbGUgPT09IG51bGwgPyBbXSA6IFtcIi0tcHJvZmlsZVwiLCBwcm9maWxlXSksXG4gIF07XG4gIGNvbnN0IHJlc3VsdCA9IHNwYXduU3luYyhcImRhdGFicmlja3NcIiwgYXJncywge1xuICAgIGN3ZDogcmVzb2x2ZShwYXRoLCBcIi4uXCIpLFxuICAgIGVuY29kaW5nOiBcInV0ZjhcIixcbiAgICBzdGRpbzogW1wiaWdub3JlXCIsIFwicGlwZVwiLCBcInBpcGVcIl0sXG4gIH0pO1xuICBjb25zdCBvdXRwdXQgPSBzdHJpbmdNb2R1bGUudHJpbVRvTnVsbChyZXN1bHQuc3Rkb3V0KTtcbiAgY29uc3QgZXJyb3IgPSBzdHJpbmdNb2R1bGUudHJpbVRvTnVsbChyZXN1bHQuc3RkZXJyKTtcbiAgaWYgKG91dHB1dCA9PT0gbnVsbCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImJ1bmRsZSB2YWxpZGF0ZSBwcm9kdWNlZCBubyBKU09OXCIsIHsgcGF0aCwgc3RhdHVzOiByZXN1bHQuc3RhdHVzLCBlcnJvciB9KTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGNvbnN0IGRhdGEgPSBqc29uLnBhcnNlUmVjb3JkKG91dHB1dCk7XG4gIGlmICghZGF0YSkge1xuICAgIGxvZ2dlci53YXJuKFwiZmFpbGVkIHRvIHBhcnNlIGJ1bmRsZSB2YWxpZGF0ZSBvdXRwdXRcIiwgeyBwYXRoLCBzdGF0dXM6IHJlc3VsdC5zdGF0dXMgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBpZiAocmVzdWx0LnN0YXR1cyAhPT0gMCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInVzaW5nIHBhcnRpYWwgYnVuZGxlIG91dHB1dFwiLCB7IHBhdGgsIHN0YXR1czogcmVzdWx0LnN0YXR1cywgZXJyb3IgfSk7XG4gIH1cbiAgcmV0dXJuIHsgcGF0aCwgZGF0YSB9O1xufVxuIl19
|
|
575
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0RHOzs7Ozs7Ozs7QUFFSCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDL0MsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN2QyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3hFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUNMLE9BQU8sRUFDUCxjQUFjLEVBQ2QsSUFBSSxFQUNKLEdBQUcsRUFDSCxNQUFNLEVBQ04sTUFBTSxJQUFJLFlBQVksR0FDdkIsTUFBTSx3QkFBd0IsQ0FBQztBQUNoQyxPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLElBQUksSUFBSSxrQkFBa0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUUxRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBaUNwQyxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUM7QUFDbEMsTUFBTSxlQUFlLEdBQTRCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM3RSxNQUFNLGlCQUFpQixHQUFHLENBQUMsZ0JBQWdCLEVBQUUsaUJBQWlCLENBQVUsQ0FBQztBQUN6RSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztBQUNoQyxNQUFNLHFCQUFxQixHQUFHO0lBQzVCLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNwQixXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUM7Q0FDZ0MsQ0FBQztBQUV2RCxxQ0FBcUM7QUFDckMsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLE1BQU0sQ0FBQztBQUVuQyxtRUFBbUU7QUFDbkUsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsOEJBQThCLENBQUM7QUFFckUsNkRBQTZEO0FBQzdELE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLHlCQUF5QixDQUFDO0FBRTNELGdFQUFnRTtBQUNoRSxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyx5QkFBeUIsQ0FBQztBQUUzRDs7OztHQUlHO0FBQ0gsTUFBTSxhQUFhLEdBQUcsb0JBQW9CLENBQUM7QUFXM0M7Ozs7R0FJRztBQUNILElBQUksYUFBYSxHQUFHLEtBQUssQ0FBQztBQUUxQiw0RUFBNEU7QUFDNUUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLE9BQU8sRUFBa0MsQ0FBQztBQUV2RSx3RkFBd0Y7QUFDeEYsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLEVBQUUsS0FBSyxFQUFFLEVBQVcsRUFBRSxPQUFPLEVBQUUsS0FBYyxFQUFFLENBQUM7QUFFeEUsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLENBQUM7S0FDekIsTUFBTSxFQUFFO0tBQ1IsU0FBUyxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7S0FDMUMsTUFBTSxDQUFDLENBQUMsS0FBYSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztLQUMzQyxNQUFNLENBQUMsQ0FBQyxLQUFhLEVBQUUsRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtJQUNyRCxPQUFPLEVBQUUscUNBQXFDO0NBQy9DLENBQUMsQ0FBQztBQUVMOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsV0FBVyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztBQUU3RixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQzNDLElBQUksRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFO0lBQzVCLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFO0lBQzVCLFVBQVUsRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFO0NBQ25DLENBQUMsQ0FBQztBQUVILE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ3RDLElBQUksRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFO0lBQzVCLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLEVBQUU7SUFDdkMsTUFBTSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUU7SUFDOUUsU0FBUyxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxRQUFRLEVBQUU7Q0FDcEQsQ0FBQyxDQUFDO0FBRUgsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO0lBQ2hDLFNBQVMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLGVBQWUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLEVBQUU7Q0FDM0YsQ0FBQyxDQUFDO0FBRUg7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsU0FBNkMsT0FBTyxDQUFDLEdBQUc7SUFFeEQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLElBQUksUUFBUSxLQUFLLFNBQVM7UUFBRSxPQUFPLFFBQVEsQ0FBQztJQUM1QyxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDbkQsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLGVBQWUsRUFBRSxJQUFJLEVBQUUsQ0FBQztJQUM1QyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDaEQsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUM3QyxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzFFLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFDRCxNQUFNLFVBQVUsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pDLE9BQU8sQ0FDTCxVQUFVLEtBQUssU0FBUztRQUN4QixNQUFNLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQztRQUM1QixVQUFVLElBQUksQ0FBQztRQUNmLFVBQVUsSUFBSSxZQUFZLENBQzNCLENBQUM7QUFDSixDQUFDO0FBRUQsb0VBQW9FO0FBQ3BFLFNBQVMsSUFBSSxDQUFDLEtBQWdCLEVBQUUsVUFBbUQsRUFBRTtJQUNuRixNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksYUFBYSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDekUsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDL0YsT0FBTztRQUNMLEdBQUcsTUFBTTthQUNOLFFBQVEsQ0FBQyxLQUFLLENBQUM7YUFDZixPQUFPLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNmLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0YsT0FBTztnQkFDTCxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDckUsR0FBRyxRQUFRO2dCQUNYLEdBQUc7YUFDSixDQUFDO1FBQ0osQ0FBQyxDQUFDO2FBQ0QsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQzthQUMvQixRQUFRLEVBQUU7S0FDZCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsTUFBTSxDQUFDLEtBQWdCLEVBQUUsVUFBeUIsRUFBRTtJQUMzRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3hDLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQWUsT0FBTyxDQUFDLE9BQU8sSUFBSSxlQUFlLENBQUMsQ0FBQztJQUNsRixPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUM7UUFDckIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDaEIsS0FBSyxNQUFNLE1BQU0sSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDN0IsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUM1QyxLQUFLLE1BQU0sR0FBRyxJQUFJLFVBQVUsRUFBRSxDQUFDO3dCQUM3QixNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO3dCQUNoRCxJQUFJLEtBQUssS0FBSyxJQUFJOzRCQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxDQUFDO29CQUNuRCxDQUFDO2dCQUNILENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxJQUFJLENBQUMsS0FBZ0IsRUFBRSxVQUF5QixFQUFFO0lBQ2hFLE9BQU8sTUFBTSxDQUFDLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDO0FBQzdDLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FDbEIsS0FBZ0IsRUFDaEIsVUFBbUQsRUFBRTtJQUVyRCxPQUFPLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxPQUFnQjtJQUNwQyxNQUFNLElBQUksR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFdBQVcsRUFBRSxDQUFDO0lBQzdELElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3BELEtBQUssTUFBTSxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQztRQUM5RSxNQUFNLEtBQUssR0FBc0IsWUFBWSxDQUFDO1FBQzlDLElBQUksSUFBSSxLQUFLLFNBQVMsSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDL0MsT0FBTyxDQUFDLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFlBQVksQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQVMsSUFBSSxDQUFDLEdBQUcsS0FBZTtJQUM5QixPQUFPLEtBQUs7U0FDVCxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUMxQixNQUFNLENBQUMsT0FBTyxDQUFDO1NBQ2YsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2YsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLE1BQU0sQ0FDcEIsVUFBbUIsRUFDbkIsS0FBZ0IsRUFDaEIsT0FBdUI7SUFFdkIsT0FBTyxZQUFZLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7QUFDckUsQ0FBQztBQUVEOzs7R0FHRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQ3JCLFVBQW1CLEVBQ25CLEtBQWdCLEVBQ2hCLE9BQXVCO0lBRXZCLE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUNoRixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsVUFBbUIsRUFDbkIsS0FBZ0IsRUFDaEIsUUFBZ0IsRUFDaEIsT0FBdUI7SUFFdkIsT0FBTyxnQkFBZ0IsQ0FBQyxVQUFVLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFDLElBQUksUUFBUSxDQUFDO0FBQzVGLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FDekIsVUFBbUIsRUFDbkIsS0FBZ0IsRUFDaEIsUUFBZ0IsRUFDaEIsT0FBdUI7SUFFdkIsTUFBTSxRQUFRLEdBQUcsY0FBYyxDQUFDLFVBQVUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ3RFLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FDbEIsVUFBeUQsRUFDekQsS0FBZ0IsRUFDaEIsU0FBcUMsRUFDckMsT0FBdUI7SUFFdkIsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDakUsT0FBTyxVQUFVLENBQUMsTUFBTSxHQUFHLENBQUM7UUFDMUIsQ0FBQyxDQUFDLFVBQVU7UUFDWixDQUFDLENBQUMsWUFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQzlELENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLEtBQWM7SUFDdEMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN0QyxPQUFPLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDakUsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxVQUFVLFVBQVUsQ0FBQyxHQUFtQjtJQUM1QyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsS0FBSyxZQUFZLENBQUM7SUFDL0UsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQztJQUNsRSxJQUFJLFFBQVEsS0FBSyxLQUFLO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDekMsMEVBQTBFO0lBQzFFLDZFQUE2RTtJQUM3RSwyRUFBMkU7SUFDM0UsSUFBSSxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDM0IsSUFBSSxVQUFVLElBQUksa0JBQWtCLEVBQUU7WUFBRSxPQUFPLFNBQVMsQ0FBQztRQUN6RCxJQUFJLENBQUMsZUFBZSxFQUFFO1lBQUUsT0FBTyxTQUFTLENBQUM7SUFDM0MsQ0FBQztJQUNELE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO0lBQy9FLE1BQU0sSUFBSSxHQUFHLFlBQVksQ0FBQyxDQUFDLFFBQVEsRUFBRSxPQUFPLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FDckUsY0FBYyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FDbEMsQ0FBQztJQUNGLElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxJQUFJLEtBQUssU0FBUztRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzlELDJFQUEyRTtJQUMzRSxzREFBc0Q7SUFDdEQsSUFBSSxhQUFhO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDL0IsNEVBQTRFO0lBQzVFLDhFQUE4RTtJQUM5RSwyQkFBMkI7SUFDM0IsSUFBSSxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQztRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3JFLG9CQUFvQixFQUFFLENBQUM7SUFDdkIsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7O0dBY0c7QUFDSCxTQUFTLFNBQVMsQ0FBQyxLQUFjO0lBQy9CLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sZ0JBQWdCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUQsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNDLElBQUksTUFBTTtRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQzFCLE1BQU0sTUFBTSxHQUFHLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDcEMsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSxTQUFTLGdCQUFnQixDQUFDLEtBQWM7SUFDdEMsTUFBTSxNQUFNLEdBQUcsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pELElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQy9CLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQztJQUN6QyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDaEMsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUM7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNsQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLEdBQUcsSUFBSSxFQUFFLENBQUM7SUFDbkQsTUFBTSxNQUFNLEdBQTJCLEVBQUUsQ0FBQztJQUMxQyxLQUFLLE1BQU0sS0FBSyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSTtZQUFFLFNBQVM7UUFDMUIsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUMxQyxJQUFJLEtBQUssS0FBSyxJQUFJO1lBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDakQsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLGVBQWUsR0FBRyxjQUFjLENBQUMsT0FBTyxDQUFDLEdBQVksRUFBRTtJQUMzRCxJQUFJLENBQUM7UUFDSCw2RUFBNkU7UUFDN0UseUNBQXlDO1FBQ3pDLE1BQU0sU0FBUyxHQUFHLGFBQWEsQ0FBQztRQUNoQyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbEQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0FBQ0gsQ0FBQyxDQUFDLENBQUM7QUFFSDs7Ozs7Ozs7Ozs7OztHQWFHO0FBQ0gsTUFBTSxZQUFZLEdBQUcsY0FBYyxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQXVDLEVBQUU7SUFDeEYsSUFBSSxDQUFDLGVBQWUsRUFBRTtRQUFFLE9BQU8sU0FBUyxDQUFDO0lBQ3pDLE1BQU0sU0FBUyxHQUFHLGFBQWEsQ0FBQztJQUNoQyxPQUFPLENBQUMsTUFBTSxNQUFNLGtDQUFDLGtCQUFrQixDQUFDLFNBQVMsRUFBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FDL0MsQ0FBQztBQUM3QixDQUFDLENBQUMsQ0FBQztBQUVIOzs7Ozs7Ozs7R0FTRztBQUNILFNBQVMsb0JBQW9CO0lBQzNCLEtBQUssWUFBWSxFQUFFO1NBQ2hCLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQ2YsSUFBSSxDQUFDLE1BQU07WUFBRSxPQUFPO1FBQ3BCLElBQUksQ0FBQztZQUNILElBQUksTUFBTSxDQUFDLG1CQUFtQixFQUFFLEVBQUUsTUFBTTtnQkFBRSxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQ2pFLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxxREFBcUQ7UUFDdkQsQ0FBQztJQUNILENBQUMsQ0FBQztTQUNELEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUM1QixDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLFNBQVMsY0FBYyxDQUFDLEtBQWM7SUFDcEMsTUFBTSxNQUFNLEdBQUcsV0FBVyxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QyxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUM3QyxDQUFDO0FBRUQsd0VBQXdFO0FBQ3hFLFNBQVMsTUFBTSxDQUFDLEdBQW1CO0lBQ2pDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxpQkFBaUIsQ0FBQztRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3JELE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hELE9BQU8sWUFBWSxDQUFDLENBQUMsUUFBUSxFQUFFLEdBQUcsWUFBWSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FDakUsVUFBVSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsQ0FDbkMsQ0FBQztBQUNKLENBQUM7QUFFRCxpRkFBaUY7QUFDakYsU0FBUyxZQUFZLENBQ25CLElBQXVCLEVBQ3ZCLEdBQThCLEVBQzlCLE1BQStCO0lBRS9CLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDMUMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQztJQUNyQyxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ3ZGLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxJQUFJLENBQ1gsTUFBb0IsRUFDcEIsR0FBWTtJQUVaLE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQztRQUNyQixDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUNoQixRQUFRLE1BQU0sRUFBRSxDQUFDO2dCQUNmLEtBQUssS0FBSztvQkFDUixNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUM7b0JBQ2xCLE1BQU07Z0JBQ1IsS0FBSyxRQUFRO29CQUNYLE1BQU0sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUNsQixNQUFNO2dCQUNSLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQztvQkFDZCxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQy9CLElBQUksTUFBTTt3QkFBRSxNQUFNLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3pDLE1BQU07Z0JBQ1IsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7R0FHRztBQUNILFNBQVMsY0FBYyxDQUFDLEdBQVcsRUFBRSxLQUF3QjtJQUMzRCxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDM0IsTUFBTSxJQUFJLEdBQUcsa0JBQWtCLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDOUQsTUFBTSxRQUFRLEdBQ1osSUFBSTtRQUNKLFlBQVksS0FBSyxTQUFTO1FBQzFCLENBQUMsVUFBVSxDQUFDLFlBQVksQ0FBQztRQUN6QixZQUFZLEtBQUssSUFBSTtRQUNyQixDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNsQyxDQUFDLENBQUMsSUFBSTtRQUNOLENBQUMsQ0FBQyxTQUFTLENBQUM7SUFDaEIsS0FBSyxJQUFJLEdBQUcsR0FBRyxLQUFLLEdBQUksR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzNDLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNoQyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxNQUFNLEVBQUU7Z0JBQUUsT0FBTyxJQUFJLENBQUM7UUFDNUMsQ0FBQztRQUNELElBQUksUUFBUSxLQUFLLFNBQVMsSUFBSSxHQUFHLEtBQUssUUFBUTtZQUFFLE1BQU07SUFDeEQsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCx5RUFBeUU7QUFDekUsU0FBUyxpQkFBaUIsQ0FBQyxHQUFXLEVBQUUsV0FBb0IsQ0FBQyxrQkFBa0IsRUFBRTtJQUMvRSxPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQztBQUN4RCxDQUFDO0FBRUQsU0FBUyxVQUFVLENBQ2pCLEdBQVcsRUFDWCxZQUErQjtJQUUvQixNQUFNLEtBQUssR0FBRyxDQUFDLEdBQUcsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxnQkFBZ0IsSUFBSSxJQUFJLEVBQUUsQ0FBQyxFQUFFLGdCQUFnQixDQUFDLENBQUM7SUFDL0YsTUFBTSxJQUFJLEdBQUcsY0FBYyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUN4QyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLElBQUksQ0FBQztRQUNILE9BQU8sUUFBUSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsTUFBTSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDcEQsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0FBQ0gsQ0FBQztBQUVELFNBQVMsY0FBYyxDQUFDLEdBQVcsRUFBRSxPQUFzQjtJQUN6RCxNQUFNLElBQUksR0FBRyxjQUFjLENBQUMsR0FBRyxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDcEQsSUFBSSxDQUFDLElBQUk7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM1QixNQUFNLElBQUksR0FBRztRQUNYLFFBQVE7UUFDUixVQUFVO1FBQ1YsVUFBVTtRQUNWLE1BQU07UUFDTixHQUFHLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztLQUNwRCxDQUFDO0lBQ0YsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLFlBQVksRUFBRSxJQUFJLEVBQUU7UUFDM0MsR0FBRyxFQUFFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDO1FBQ3hCLFFBQVEsRUFBRSxNQUFNO1FBQ2hCLEtBQUssRUFBRSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDO0tBQ2xDLENBQUMsQ0FBQztJQUNILE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RELE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JELElBQUksTUFBTSxLQUFLLElBQUksRUFBRSxDQUFDO1FBQ3BCLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0NBQWtDLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN6RixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUN0QyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLENBQUMsSUFBSSxDQUFDLHdDQUF3QyxFQUFFLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztRQUN2RixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUN0RixDQUFDO0lBQ0QsT0FBTyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztBQUN4QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBMYXllcmVkIGNvbmZpZ3VyYXRpb24gbG9va3VwOiBlbnZpcm9ubWVudCwgYC5lbnZgLCBEYXRhYnJpY2tzIGJ1bmRsZS5cbiAqXG4gKiBFdmVyeSBwYWNrYWdlIHJlc29sdmVzIHNldHRpbmdzIHRoZSBzYW1lIHdheTogdGFrZSB0aGUgY2FsbGVyJ3MgdmFsdWUsIGVsc2VcbiAqIGFuIGVudmlyb25tZW50IHZhcmlhYmxlLCBlbHNlIGEgZGVmYXVsdC4gTG9jYWwgZGV2ZWxvcG1lbnQgYWRkcyB0d28gZmFsbGJhY2tcbiAqIGxvY2F0aW9uczogYC5lbnZgIGZpbGVzIGFuZCBgcmVzb3VyY2VzLmFwcHMuPGFwcD4uY29uZmlnLmVudmAgb3Igcm9vdFxuICogYHZhcmlhYmxlc2AgaW4gYGRhdGFicmlja3MueW1sYC5cbiAqXG4gKiBUd28gdGhpbmdzIG1ha2UgaXQgY2hlYXAgdG8gY2FsbCBmcm9tIGEgaG90IHBhdGg6XG4gKlxuICogICAtIHtAbGluayB2YWx1ZXN9IGlzIExBWlkgKGFuIGBvYmplY3QuU2VxdWVuY2VgKSwgc28gYGRhdGFicmlja3MgYnVuZGxlXG4gKiAgICAgdmFsaWRhdGVgIGlzIG9ubHkgc3Bhd25lZCB3aGVuIHRoZSBlbnZpcm9ubWVudCBhbmQgYC5lbnZgIGJvdGggbWlzc2VkLlxuICogICAtIHRoZSBwYXJzZWQgYC5lbnZgIGFuZCBidW5kbGUgYXJlIGNhY2hlZCB0aHJvdWdoIHtAbGluayBjb250ZXh0LmNhY2hlZH0sIHNvXG4gKiAgICAgdGhlIHNwYXduIGhhcHBlbnMgb25jZSBwZXIgd29ya2luZyBkaXJlY3RvcnkgYW5kIGEgYGN3ZGAgY2hhbmdlIG1pc3Nlc1xuICogICAgIHJhdGhlciB0aGFuIHJldHVybmluZyBhbm90aGVyIHByb2plY3QncyBjb25maWcuXG4gKlxuICogSW5zaWRlIGEgZGVwbG95ZWQgRGF0YWJyaWNrcyBBcHAgYm90aCBmaWxlIHNvdXJjZXMgYXJlIHNraXBwZWQgYnkgZGVmYXVsdFxuICogKHtAbGluayBpc0RhdGFicmlja3NBcHBFbnZ9KTogdGhlIHBsYXRmb3JtIGhhcyBhbHJlYWR5IHR1cm5lZCB0aGVtIGludG8gcmVhbFxuICogZW52aXJvbm1lbnQgdmFyaWFibGVzLCB0aGVyZSBpcyBubyBidW5kbGUgdG8gdmFsaWRhdGUsIGFuZCB0aGUgYGRhdGFicmlja3NgXG4gKiBDTEkgaXMgbm90IG9uIHRoZSBpbWFnZS4gQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZXMgY2FuIGZvcmNlIGVpdGhlciBmaWxlXG4gKiBzb3VyY2Ugb24gb3Igb2ZmIHdoZW4gYSB0b29sIG5lZWRzIGRpZmZlcmVudCBiZWhhdmlvci5cbiAqXG4gKiBUaGUgYnVuZGxlIGlzIGdhdGVkIG9uIHRoaXMgYmVpbmcgYW4gQXBwS2l0IHByb2plY3QgYXQgYWxsLiBgZGF0YWJyaWNrcyBidW5kbGVcbiAqIHZhbGlkYXRlYCBpcyBhIHByb2Nlc3Mgc3Bhd24gbWVhc3VyZWQgaW4gc2Vjb25kcywgYW5kIGEgcGxhaW4gbGlicmFyeSBvciBDTElcbiAqIGNvbnN1bWVyIGhhcyBubyBidW5kbGUgdG8gZmluZCwgc28gdGhlIGdhdGUgcnVucyBpbiB0aHJlZSBzdGVwcyBiZWZvcmUgdGhlXG4gKiBzcGF3biBpcyBhbGxvd2VkIC0gc2VlIHtAbGluayBidW5kbGVGaWxlfTpcbiAqXG4gKiAgIDEuIGBAZGF0YWJyaWNrcy9hcHBraXRgIGlzIHJlc29sdmVkIFdJVEhPVVQgZXZhbHVhdGluZyBpdC4gSXQgaXMgYW4gb3B0aW9uYWxcbiAqICAgICAgcGVlciwgc28gYSBjb25zdW1lciB0aGF0IG5ldmVyIGluc3RhbGxlZCBpdCBpcyBub3QgYW4gQXBwS2l0IHByb2plY3QgYW5kXG4gKiAgICAgIHRoZSBidW5kbGUgaXMgbmV2ZXIgbG9hZGVkLiBUaGUgcHJvYmUgaXMgY2FjaGVkLCBzbyB0aGlzIGNvc3RzIG9uZVxuICogICAgICByZXNvbHV0aW9uIGZvciB0aGUgbGlmZSBvZiB0aGUgcHJvY2Vzcy5cbiAqICAgMi4gVGhlIGJ1bmRsZSBpcyByZWFkIChvbmNlIHBlciBjb250ZXh0KSBhbmQgbXVzdCBkZXNjcmliZSBFWEFDVExZIE9ORSBhcHBcbiAqICAgICAgd2l0aCBgY29uZmlnLmVudmAuIE5vdGhpbmcgaGVyZSBzYXlzIHdoaWNoIG9mIHNldmVyYWwgYXBwcyB0aGlzIHByb2Nlc3NcbiAqICAgICAgaXMsIHNvIGFuIGFtYmlndW91cyBidW5kbGUgY29udHJpYnV0ZXMgbm90aGluZyByYXRoZXIgdGhhbiBhIGd1ZXNzLlxuICogICAzLiBBcHBLaXQncyBleGVjdXRpb24gY29udGV4dCBjb25maXJtcyB0aGlzIHByb2Nlc3MgcmVhbGx5IGlzIHRoYXQgYXBwLiBUaGVcbiAqICAgICAgY29udGV4dCBkb2VzIG5vdCBleGlzdCB1bnRpbCBBcHBLaXQgYm9vdHMgYW5kIGBnZXRFeGVjdXRpb25Db250ZXh0KClgXG4gKiAgICAgIFRIUk9XUyB1bnRpbCB0aGVuLCBzbyB0aGUgcHJvYmUgaXMgY2F1Z2h0IGFuZCBvbmx5IHRoZSBhZmZpcm1hdGl2ZSBpc1xuICogICAgICByZW1lbWJlcmVkIC0gYSBsb29rdXAgYmVmb3JlIGJvb3Qgc3RpbGwgcmVzb2x2ZXMsIGFuZCByZS1jb25maXJtcyBsYXRlclxuICogICAgICBvbmNlIHRoZSBjb250ZXh0IGlzIGF2YWlsYWJsZS5cbiAqXG4gKiBPbmx5IHRoZSBzaW5nbGUgYXBwJ3MgYGNvbmZpZy5lbnZgIGlzIGNvbnN1bHRlZC4gUm9vdCBidW5kbGUgYHZhcmlhYmxlc2AgYXJlXG4gKiBub3Q6IHRoZXkgYXJlIGF1dGhvcmluZyBpbnB1dHMgZm9yIHRoZSBidW5kbGUgaXRzZWxmIChpbnRlcnBvbGF0ZWQgaW50b1xuICogdGFyZ2V0cywgcmVzb3VyY2VzLCBhbmQgcGF0aHMpLCBzbyB0cmVhdGluZyBvbmUgYXMgYSBwcm9jZXNzIHNldHRpbmcgcmVzb2x2ZXNcbiAqIG5hbWVzIHRoZSBkZXBsb3llZCBhcHAgbmV2ZXIgc2Vlcy5cbiAqXG4gKiBOb2RlLW9ubHkgKGBjaGlsZF9wcm9jZXNzYCwgYGZzYCwgYHByb2Nlc3NgKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgc3Bhd25TeW5jIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGNyZWF0ZVJlcXVpcmUgfSBmcm9tIFwibm9kZTptb2R1bGVcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGlzQWJzb2x1dGUsIHJlbGF0aXZlLCByZXNvbHZlLCBzZXAgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBwYXJzZUVudiB9IGZyb20gXCJub2RlOnV0aWxcIjtcbmltcG9ydCB7XG4gIGNvbnRleHQsXG4gIGZ1bmN0aW9uTW9kdWxlLFxuICBqc29uLFxuICBsb2csXG4gIG9iamVjdCxcbiAgc3RyaW5nIGFzIHN0cmluZ01vZHVsZSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBzdGF0U3luYyB9IGZyb20gXCIuL2ZpbGUudHNcIjtcbmltcG9ydCB7IHJvb3QgYXMgcmVzb2x2ZVByb2plY3RSb290IH0gZnJvbSBcIi4vcHJvamVjdC50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiY29uZmlnXCIpO1xuXG5leHBvcnQgdHlwZSBDb25maWdLZXkgPSBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXTtcblxuLyoqIFdoZXJlIGEgdmFsdWUgbWF5IGNvbWUgZnJvbSwgY29uc3VsdGVkIGluIHRoZSBvcmRlciBnaXZlbi4gKi9cbmV4cG9ydCB0eXBlIENvbmZpZ1NvdXJjZSA9IFwiZW52XCIgfCBcImRvdGVudlwiIHwgXCJidW5kbGVcIjtcblxuZXhwb3J0IGludGVyZmFjZSBDb25maWdPcHRpb25zIHtcbiAgLyoqXG4gICAqIE91dGVybW9zdCBuYW1lc3BhY2VzIHRyaWVkIGJlZm9yZSBlYWNoIGtleS4gRGVmYXVsdHMgdG8gYERCWF9UT09MU2AuXG4gICAqL1xuICBzY29wZT86IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAvKiogQ2FwYWJpbGl0eSBuYW1lc3BhY2VzIGluc2VydGVkIGFmdGVyIHRoZSBzY29wZSBhbmQgYmVmb3JlIGVhY2gga2V5LiAqL1xuICBwcmVmaXg/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqIERpcmVjdG9yeSB0byByZXNvbHZlIGAuZW52YCBhbmQgdGhlIGJ1bmRsZSBmcm9tLiBEZWZhdWx0OiBgcHJvY2Vzcy5jd2QoKWAuICovXG4gIGN3ZD86IHN0cmluZztcbiAgLyoqIFNvdXJjZXMgaW4gcHJlY2VkZW5jZSBvcmRlci4gRGVmYXVsdDogYGVudmAsIGBkb3RlbnZgLCBgYnVuZGxlYC4gKi9cbiAgc291cmNlcz86IENvbmZpZ1NvdXJjZSB8IHJlYWRvbmx5IENvbmZpZ1NvdXJjZVtdO1xufVxuXG4vKiogT25lIHJlc29sdmVkIHZhbHVlLCB0YWdnZWQgd2l0aCB0aGUga2V5IGFuZCBzb3VyY2UgaXQgY2FtZSBmcm9tLiAqL1xuaW50ZXJmYWNlIENvbmZpZ1ZhbHVlIHtcbiAga2V5OiBzdHJpbmc7XG4gIHNvdXJjZTogQ29uZmlnU291cmNlO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG4vKiogQSBjb25maWcgZmlsZSBmb3VuZCBvbiBkaXNrLCB3aXRoIGl0cyBwYXJzZWQgY29udGVudHMuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZ0ZpbGUge1xuICBwYXRoOiBzdHJpbmc7XG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5jb25zdCBERUZBVUxUX1NDT1BFID0gXCJEQlhfVE9PTFNcIjtcbmNvbnN0IERFRkFVTFRfU09VUkNFUzogcmVhZG9ubHkgQ29uZmlnU291cmNlW10gPSBbXCJlbnZcIiwgXCJkb3RlbnZcIiwgXCJidW5kbGVcIl07XG5jb25zdCBCVU5ETEVfRklMRV9OQU1FUyA9IFtcImRhdGFicmlja3MueW1sXCIsIFwiZGF0YWJyaWNrcy55YW1sXCJdIGFzIGNvbnN0O1xuY29uc3QgRE9URU5WX0ZJTEVfTkFNRSA9IFwiLmVudlwiO1xuY29uc3QgTk9ERV9FTlZfQUxURVJOQVRJVkVTID0ge1xuICBwcm9kdWN0aW9uOiBbXCJwcm9kXCJdLFxuICBkZXZlbG9wbWVudDogW1wiZGV2XCJdLFxufSBhcyBjb25zdCBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+O1xuXG4vKiogSGlnaGVzdCB2YWxpZCBUQ1AgcG9ydCBudW1iZXIuICovXG5leHBvcnQgY29uc3QgTUFYX1RDUF9QT1JUID0gNjVfNTM1O1xuXG4vKiogQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZSBmb3Ige0BsaW5rIGlzRGF0YWJyaWNrc0FwcEVudn0uICovXG5leHBvcnQgY29uc3QgREFUQUJSSUNLU19BUFBfRU5WX0tFWSA9IFwiREJYX1RPT0xTX0RBVEFCUklDS1NfQVBQX0VOVlwiO1xuXG4vKiogQm9vbGVhbiBlbnZpcm9ubWVudCBvdmVycmlkZSBmb3IgcHJvamVjdCBgLmVudmAgcmVhZHMuICovXG5leHBvcnQgY29uc3QgQ09ORklHX0RPVEVOVl9LRVkgPSBcIkRCWF9UT09MU19DT05GSUdfRE9URU5WXCI7XG5cbi8qKiBCb29sZWFuIGVudmlyb25tZW50IG92ZXJyaWRlIGZvciBEYXRhYnJpY2tzIGJ1bmRsZSByZWFkcy4gKi9cbmV4cG9ydCBjb25zdCBDT05GSUdfQlVORExFX0tFWSA9IFwiREJYX1RPT0xTX0NPTkZJR19CVU5ETEVcIjtcblxuLyoqXG4gKiBUaGUgT1BUSU9OQUwgQXBwS2l0IHBlZXIgd2hvc2UgcHJlc2VuY2UgbWFya3MgdGhpcyBhcyBhIERhdGFicmlja3MgQXBwXG4gKiBwcm9qZWN0LiBIZWxkIGFzIGEgY29uc3RhbnQgc28gdGhlIHJlc29sdmUgcHJvYmUgYW5kIHRoZSBsYXp5IGltcG9ydCBuYW1lIGl0XG4gKiBvbmNlLCBhbmQgc28gbmVpdGhlciBzaXRlIGNhcnJpZXMgYSBsaXRlcmFsIGEgYnVuZGxlciB3b3VsZCB0cnkgdG8gZm9sbG93LlxuICovXG5jb25zdCBBUFBLSVRfTU9EVUxFID0gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcblxuLyoqXG4gKiBUaGUgb25lIHRoaW5nIHRoaXMgbW9kdWxlIG5lZWRzIGZyb20gQXBwS2l0OiB3aGV0aGVyIGEgcmVhbCBleGVjdXRpb24gY29udGV4dFxuICogaXMgYWN0aXZlLiBUeXBlZCBzdHJ1Y3R1cmFsbHkgc28gYW4gT1BUSU9OQUwgcGVlciBuZXZlciBiZWNvbWVzIGEgdHlwZVxuICogZGVwZW5kZW5jeSwgYW5kIGBjbGllbnRgIGlzIGB1bmtub3duYCBiZWNhdXNlIGl0cyBwcmVzZW5jZSBpcyBhbGwgdGhhdCBpcyByZWFkLlxuICovXG50eXBlIEFwcEtpdE1vZHVsZSA9IHtcbiAgZ2V0RXhlY3V0aW9uQ29udGV4dCgpOiB7IGNsaWVudD86IHVua25vd24gfSB8IHVuZGVmaW5lZDtcbn07XG5cbi8qKlxuICogV2hldGhlciBBcHBLaXQncyBleGVjdXRpb24gY29udGV4dCBoYXMgRVZFUiBiZWVuIG9ic2VydmVkLiBMYXRjaGluZyBpcyB0aGVcbiAqIHBvaW50OiBhIGNvbnRleHQgY29uZmlybXMgdGhpcyBwcm9jZXNzIGlzIHRoZSBidW5kbGUncyBhcHAsIGFuZCB0aGF0IGZhY3QgZG9lc1xuICogbm90IHN0b3AgYmVpbmcgdHJ1ZSB3aGVuIGEgbGF0ZXIgbG9va3VwIGhhcHBlbnMgb3V0c2lkZSBhIHJlcXVlc3Qgc2NvcGUuXG4gKi9cbmxldCBhcHBLaXRDb250ZXh0ID0gZmFsc2U7XG5cbi8qKiBGbGF0dGVuZWQgQXBwIGBjb25maWcuZW52YCBwZXIgcGFyc2VkIGJ1bmRsZSAtIHNlZSB7QGxpbmsgYnVuZGxlQXBwfS4gKi9cbmNvbnN0IEJVTkRMRV9BUFBfQ0FDSEUgPSBuZXcgV2Vha01hcDxvYmplY3QsIFJlY29yZDxzdHJpbmcsIHN0cmluZz4+KCk7XG5cbi8qKiBFeGFjdCBwcm9jZXNzLWVudmlyb25tZW50IGxvb2t1cCBmb3IgY2FsbGVycyB0aGF0IGRvIG5vdCByZWFkIGxvY2FsIGNvbmZpZyBmaWxlcy4gKi9cbmV4cG9ydCBjb25zdCBFTlZfT05MWSA9IHsgc2NvcGU6IFtdIGFzIGNvbnN0LCBzb3VyY2VzOiBcImVudlwiIGFzIGNvbnN0IH07XG5cbmV4cG9ydCBjb25zdCBidW5kbGVWYWx1ZSA9IHpcbiAgLnN0cmluZygpXG4gIC50cmFuc2Zvcm0oKHZhbHVlOiBzdHJpbmcpID0+IHZhbHVlLnRyaW0oKSlcbiAgLnJlZmluZSgodmFsdWU6IHN0cmluZykgPT4gdmFsdWUubGVuZ3RoID4gMClcbiAgLnJlZmluZSgodmFsdWU6IHN0cmluZykgPT4gIS9cXCRcXHtbXn1dK1xcfS8udGVzdCh2YWx1ZSksIHtcbiAgICBtZXNzYWdlOiBcIkludGVycG9sYXRlZCB2YWx1ZXMgYXJlIG5vdCBhbGxvd2VkXCIsXG4gIH0pO1xuXG4vKipcbiAqIFRoZSBHRU5FUklDIHNoYXBlIG9mIGEgYnVuZGxlIHJlc291cmNlOiBhIG5hbWUsIGFuZCB3aGF0ZXZlciBlbHNlIHRoZSByZXNvdXJjZVxuICogdHlwZSBjYXJyaWVzLiBEZWxpYmVyYXRlbHkgdW5vcGluaW9uYXRlZCBhbmQgYHBhc3N0aHJvdWdoKClgIC0gdGhlIGNvbmNyZXRlXG4gKiByZXNvdXJjZSBraW5kcyAoYHNxbF93YXJlaG91c2VgLCBgZ2VuaWVfc3BhY2VgLCBgcG9zdGdyZXNgLCAuLi4pIGFyZVxuICogRGF0YWJyaWNrcy1BcHAgY29uY2VwdHMgdGhhdCBiZWxvbmcgdG8gdGhlIHBhY2thZ2UgdGhhdCByZXNvbHZlcyB0aGVtLCBzb1xuICogbm9kZS1hcHBraXQgYC5leHRlbmQoKWBzIHRoaXMgcmF0aGVyIHRoYW4gdGhpcyBtb2R1bGUga25vd2luZyBhYm91dCB0aGVtLlxuICovXG5leHBvcnQgY29uc3QgYnVuZGxlUmVzb3VyY2VTY2hlbWEgPSB6Lm9iamVjdCh7IG5hbWU6IGJ1bmRsZVZhbHVlLm9wdGlvbmFsKCkgfSkucGFzc3Rocm91Z2goKTtcblxuZXhwb3J0IGNvbnN0IGJ1bmRsZUVudkVudHJ5U2NoZW1hID0gei5vYmplY3Qoe1xuICBuYW1lOiBidW5kbGVWYWx1ZS5vcHRpb25hbCgpLFxuICB2YWx1ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB2YWx1ZV9mcm9tOiBidW5kbGVWYWx1ZS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVBcHBTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IGJ1bmRsZVZhbHVlLm9wdGlvbmFsKCksXG4gIHNvdXJjZV9jb2RlX3BhdGg6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgY29uZmlnOiB6Lm9iamVjdCh7IGVudjogei5hcnJheShidW5kbGVFbnZFbnRyeVNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxuICByZXNvdXJjZXM6IHouYXJyYXkoYnVuZGxlUmVzb3VyY2VTY2hlbWEpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgYnVuZGxlQXBwc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgcmVzb3VyY2VzOiB6Lm9iamVjdCh7IGFwcHM6IHoucmVjb3JkKHouc3RyaW5nKCksIGJ1bmRsZUFwcFNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxufSk7XG5cbi8qKlxuICogRGV0ZWN0IGEgRGF0YWJyaWNrcyBBcHAgcnVudGltZSBmcm9tIGl0cyByZXF1aXJlZCBuYW1lLCBob3N0LCBhbmQgcG9ydC5cbiAqXG4gKiBgREJYX1RPT0xTX0RBVEFCUklDS1NfQVBQX0VOVmAgdGFrZXMgcHJlY2VkZW5jZSB3aGVuIGl0IGNvbnRhaW5zIGEgcmVjb2duaXplZFxuICogYm9vbGVhbiB2YWx1ZS4gVGhpcyBsZXRzIGxvY2FsIHRvb2xzIGVtdWxhdGUgdGhlIGRlcGxveWVkIHJ1bnRpbWUgKGB0cnVlYCkgb3JcbiAqIGxldHMgdW51c3VhbCBkZXBsb3llZCBwcm9jZXNzZXMgcmV0YWluIGxvY2FsIGNvbmZpZyBsb29rdXAgKGBmYWxzZWApLiBBblxuICogYWJzZW50IG9yIHVucmVjb2duaXplZCBvdmVycmlkZSBmYWxscyBiYWNrIHRvIHN0cnVjdHVyYWwgZGV0ZWN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRhYnJpY2tzQXBwRW52KFxuICBzb3VyY2U6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gPSBwcm9jZXNzLmVudixcbik6IGJvb2xlYW4ge1xuICBjb25zdCBvdmVycmlkZSA9IG9iamVjdC50b0Jvb2xlYW4oc291cmNlW0RBVEFCUklDS1NfQVBQX0VOVl9LRVldKTtcbiAgaWYgKG92ZXJyaWRlICE9PSB1bmRlZmluZWQpIHJldHVybiBvdmVycmlkZTtcbiAgY29uc3QgYXBwTmFtZSA9IHNvdXJjZS5EQVRBQlJJQ0tTX0FQUF9OQU1FPy50cmltKCk7XG4gIGNvbnN0IGhvc3QgPSBzb3VyY2UuREFUQUJSSUNLU19IT1NUPy50cmltKCk7XG4gIGNvbnN0IHBvcnQgPSBzb3VyY2UuREFUQUJSSUNLU19BUFBfUE9SVD8udHJpbSgpO1xuICBpZiAoIWFwcE5hbWUgfHwgIWhvc3QgfHwgIXBvcnQpIHJldHVybiBmYWxzZTtcbiAgdHJ5IHtcbiAgICBpZiAoIVtcImh0dHA6XCIsIFwiaHR0cHM6XCJdLmluY2x1ZGVzKG5ldyBVUkwoaG9zdCkucHJvdG9jb2wpKSByZXR1cm4gZmFsc2U7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBjb25zdCBwb3J0TnVtYmVyID0gb2JqZWN0LnRvTnVtYmVyKHBvcnQpO1xuICByZXR1cm4gKFxuICAgIHBvcnROdW1iZXIgIT09IHVuZGVmaW5lZCAmJlxuICAgIE51bWJlci5pc0ludGVnZXIocG9ydE51bWJlcikgJiZcbiAgICBwb3J0TnVtYmVyID49IDEgJiZcbiAgICBwb3J0TnVtYmVyIDw9IE1BWF9UQ1BfUE9SVFxuICApO1xufVxuXG4vKiogQ2FuZGlkYXRlIG5hbWVzIGluIHNjb3BlLCBwcmVmaXgsIGFuZCBpbnB1dCBwcmVjZWRlbmNlIG9yZGVyLiAqL1xuZnVuY3Rpb24ga2V5cyhpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBQaWNrPENvbmZpZ09wdGlvbnMsIFwic2NvcGVcIiB8IFwicHJlZml4XCI+ID0ge30pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IHNjb3BlcyA9IG9iamVjdC5zZXF1ZW5jZShvcHRpb25zLnNjb3BlID8/IERFRkFVTFRfU0NPUEUpLnRvQXJyYXkoKTtcbiAgY29uc3QgcHJlZml4ZXMgPSBvcHRpb25zLnByZWZpeCA9PT0gdW5kZWZpbmVkID8gW10gOiBvYmplY3Quc2VxdWVuY2Uob3B0aW9ucy5wcmVmaXgpLnRvQXJyYXkoKTtcbiAgcmV0dXJuIFtcbiAgICAuLi5vYmplY3RcbiAgICAgIC5zZXF1ZW5jZShpbnB1dClcbiAgICAgIC5mbGF0TWFwKChrZXkpID0+IHtcbiAgICAgICAgY29uc3QgcHJlZml4ZWQgPSBwcmVmaXhlcy5sZW5ndGggPiAwID8gcHJlZml4ZXMubWFwKChwcmVmaXgpID0+IGpvaW4ocHJlZml4LCBrZXkpKSA6IFtrZXldO1xuICAgICAgICByZXR1cm4gW1xuICAgICAgICAgIC4uLnNjb3Blcy5mbGF0TWFwKChzY29wZSkgPT4gcHJlZml4ZWQubWFwKChrZXkpID0+IGpvaW4oc2NvcGUsIGtleSkpKSxcbiAgICAgICAgICAuLi5wcmVmaXhlZCxcbiAgICAgICAgICBrZXksXG4gICAgICAgIF07XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoa2V5KSA9PiBrZXkubGVuZ3RoID4gMClcbiAgICAgIC5kaXN0aW5jdCgpLFxuICBdO1xufVxuXG4vKipcbiAqIEV2ZXJ5IHZhbHVlIHRoYXQgcmVzb2x2ZXMgZm9yIGBpbnB1dGAsIGluIHNvdXJjZS10aGVuLWtleSBwcmVjZWRlbmNlIG9yZGVyLFxuICogYXMgYSBMQVpZIHNlcXVlbmNlOiBub3RoaW5nIHBhc3QgdGhlIGZpcnN0IGNvbnN1bWVkIGVsZW1lbnQgaXMgcmVhZCwgc29cbiAqIGB2YWx1ZXMoa2V5KS5maXJzdCgpYCBuZXZlciBzcGF3bnMgdGhlIERhdGFicmlja3MgQ0xJIHdoZW4gdGhlIGVudmlyb25tZW50XG4gKiBhbHJlYWR5IGFuc3dlcmVkLlxuICpcbiAqL1xuZnVuY3Rpb24gdmFsdWVzKGlucHV0OiBDb25maWdLZXksIG9wdGlvbnM6IENvbmZpZ09wdGlvbnMgPSB7fSk6IG9iamVjdC5TZXF1ZW5jZTxDb25maWdWYWx1ZT4ge1xuICBjb25zdCBjYW5kaWRhdGVzID0ga2V5cyhpbnB1dCwgb3B0aW9ucyk7XG4gIGNvbnN0IHNvdXJjZXMgPSBvYmplY3Quc2VxdWVuY2U8Q29uZmlnU291cmNlPihvcHRpb25zLnNvdXJjZXMgPz8gREVGQVVMVF9TT1VSQ0VTKTtcbiAgcmV0dXJuIG9iamVjdC5zZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCk6IEdlbmVyYXRvcjxDb25maWdWYWx1ZT4ge1xuICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykge1xuICAgICAgICBmb3IgKGNvbnN0IG1hcCBvZiByZWFkKHNvdXJjZSwgb3B0aW9ucy5jd2QpKSB7XG4gICAgICAgICAgZm9yIChjb25zdCBrZXkgb2YgY2FuZGlkYXRlcykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBzdHJpbmdNb2R1bGUudHJpbVRvTnVsbChtYXBba2V5XSk7XG4gICAgICAgICAgICBpZiAodmFsdWUgIT09IG51bGwpIHlpZWxkIHsga2V5LCBzb3VyY2UsIHZhbHVlIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogVGhlIGZpcnN0IHZhbHVlIHRoYXQgcmVzb2x2ZXMgZm9yIGBpbnB1dGAsIG9yIGB1bmRlZmluZWRgLlxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCBkb21haW4gPSBjb25maWcudGV4dChbXCJUVU5ORUxfUFVCTElDX0RPTUFJTlwiLCBcIlBVQkxJQ19ET01BSU5cIl0pO1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGV4dChpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBDb25maWdPcHRpb25zID0ge30pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdmFsdWVzKGlucHV0LCBvcHRpb25zKS5hdCgwKT8udmFsdWU7XG59XG5cbi8qKlxuICogVGhlIFBSSU1BUlkgKGZ1bGx5LXNjb3BlZCkgbmFtZSBmb3IgYGlucHV0YCAtIHdoYXQgdG8gcHJpbnQgaW4gYSBsb2cgbGluZSBvciBhblxuICogZXJyb3IsIHNvIHRoZSBtZXNzYWdlIG5hbWVzIHRoZSB2YXJpYWJsZSBhIHJlYWRlciBzaG91bGQgc2V0LiBEbyBub3QgaW5kZXhcbiAqIGBrZXlzKC4uLilbMF1gIGZvciB0aGlzIGlmIGBpbnB1dGAgbWF5IGJlIGEgYmFyZSBzdHJpbmcuXG4gKlxuICogQGV4YW1wbGVcbiAqIGxvZ2dlci53YXJuKGAke2NvbmZpZy5uYW1lKEpXVF9TRUNSRVRfRU5WKX0gaXMgbm90IHNldGApO1xuICovXG5leHBvcnQgZnVuY3Rpb24gbmFtZShcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9uczogUGljazxDb25maWdPcHRpb25zLCBcInNjb3BlXCIgfCBcInByZWZpeFwiPiA9IHt9LFxuKTogc3RyaW5nIHtcbiAgcmV0dXJuIGtleXMoaW5wdXQsIG9wdGlvbnMpWzBdID8/IFwiXCI7XG59XG5cbi8qKlxuICogU2FmZSBgLmVudi48bmFtZT5gIHN1ZmZpeGVzIGZvciBhIE5vZGUgZW52aXJvbm1lbnQsIGV4YWN0IHNwZWxsaW5nIGZpcnN0LlxuICogS25vd24gbG9uZyBhbmQgc2hvcnQgbmFtZXMgYXJlIGludGVyY2hhbmdlYWJsZTsgdW5rbm93biBuYW1lcyBwYXNzIHRocm91Z2guXG4gKi9cbmZ1bmN0aW9uIG5vZGVFbnZOYW1lcyhub2RlRW52OiB1bmtub3duKTogc3RyaW5nW10ge1xuICBjb25zdCBuYW1lID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwobm9kZUVudik/LnRvTG93ZXJDYXNlKCk7XG4gIGlmICghbmFtZSB8fCAhL15bYS16MC05Xy1dKyQvLnRlc3QobmFtZSkpIHJldHVybiBbXTtcbiAgZm9yIChjb25zdCBbY2Fub25pY2FsLCBhbHRlcm5hdGl2ZXNdIG9mIE9iamVjdC5lbnRyaWVzKE5PREVfRU5WX0FMVEVSTkFUSVZFUykpIHtcbiAgICBjb25zdCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10gPSBhbHRlcm5hdGl2ZXM7XG4gICAgaWYgKG5hbWUgPT09IGNhbm9uaWNhbCB8fCBuYW1lcy5pbmNsdWRlcyhuYW1lKSkge1xuICAgICAgcmV0dXJuIFsuLi5vYmplY3Quc2VxdWVuY2UobmFtZSwgY2Fub25pY2FsLCBhbHRlcm5hdGl2ZXMpLmRpc3RpbmN0KCldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gW25hbWVdO1xufVxuXG5mdW5jdGlvbiBqb2luKC4uLnBhcnRzOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gIHJldHVybiBwYXJ0c1xuICAgIC5tYXAoKHBhcnQpID0+IHBhcnQudHJpbSgpKVxuICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAuam9pbihcIl9cIik7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHN0cmluZzogYGNvbmZpZ3VyZWRgIHdoZW4gbm9uLWVtcHR5LCBlbHNlIHtAbGluayB0ZXh0fSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqXG4gKiBUaGUgY29lcmNpb24gcnVsZXMgYXJlIGRlbGliZXJhdGVseSBsb29zZSAoYG9uYCAvIGB5ZXNgIC8gYDFgIGFyZSBhbGxcbiAqIGB0cnVlYCkgYmVjYXVzZSB2YWx1ZXMgbWF5IGNvbWUgZnJvbSBhIGZpbGUgYSBodW1hbiB0eXBlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uZmlnLnN0cmluZyhvcHRpb25zLmhvc3QsIFwiU01UUF9IT1NUXCIpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5nKFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBzdHJpbmdNb2R1bGUudHJpbVRvTnVsbChjb25maWd1cmVkKSA/PyB0ZXh0KGlucHV0LCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgYm9vbGVhbiB0aHJvdWdoIGBvYmplY3QudG9Cb29sZWFuYC4gYHVuZGVmaW5lZGAgd2hlbiBuZWl0aGVyIHNvdXJjZVxuICogaXMgaW50ZXJwcmV0YWJsZSwgc28gdGhlIGNhbGxlciBwaWNrcyBhIGRlZmF1bHQgd2l0aCBgPz9gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYm9vbGVhbihcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBib29sZWFuIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIG9iamVjdC50b0Jvb2xlYW4oY29uZmlndXJlZCkgPz8gb2JqZWN0LnRvQm9vbGVhbih0ZXh0KGlucHV0LCBvcHRpb25zKSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHBvc2l0aXZlIG51bWJlciB0aGF0IG1heSBiZSBmcmFjdGlvbmFsIChhIHNjb3JlIHRocmVzaG9sZCwgYSByYXRpbykuXG4gKiBVc2Uge0BsaW5rIHBvc2l0aXZlSW50fSBmb3IgYSBjb3VudCwgcG9ydCwgb3IgdGltZW91dC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlTnVtYmVyKFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBmYWxsYmFjazogbnVtYmVyLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIHJldHVybiB0b1Bvc2l0aXZlTnVtYmVyKGNvbmZpZ3VyZWQpID8/IHRvUG9zaXRpdmVOdW1iZXIodGV4dChpbnB1dCwgb3B0aW9ucykpID8/IGZhbGxiYWNrO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBwb3NpdGl2ZSBpbnRlZ2VyIChhIHBvcnQsIGEgdGltZW91dCwgYSBwYWdlIHNpemUpLCBmbG9vcmVkLiBBXG4gKiBub24tbnVtZXJpYyBvciBub24tcG9zaXRpdmUgdmFsdWUgaXMgdHJlYXRlZCBhcyBBQlNFTlQgcmF0aGVyIHRoYW4gZmF0YWwgLVxuICogdGhlc2UgYXJlIGNlaWxpbmdzIHdoZXJlIGEgc2FuZSBkZWZhdWx0IGJlYXRzIGEgYm9vdCBmYWlsdXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpdmVJbnQoXG4gIGNvbmZpZ3VyZWQ6IHVua25vd24sXG4gIGlucHV0OiBDb25maWdLZXksXG4gIGZhbGxiYWNrOiBudW1iZXIsXG4gIG9wdGlvbnM/OiBDb25maWdPcHRpb25zLFxuKTogbnVtYmVyIHtcbiAgY29uc3QgcmVzb2x2ZWQgPSBwb3NpdGl2ZU51bWJlcihjb25maWd1cmVkLCBpbnB1dCwgZmFsbGJhY2ssIG9wdGlvbnMpO1xuICByZXR1cm4gTWF0aC5mbG9vcihyZXNvbHZlZCk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGxpc3QgdGhyb3VnaCBgc3RyaW5nLnBhcnNlTGlzdGAsIHNvIGFuIGFycmF5IGZyb20gdHlwZWQgY29uZmlnIGFuZCBhXG4gKiBgXCJhLCBiIGNcImAgc3RyaW5nIG5vcm1hbGl6ZSBpZGVudGljYWxseS4gYFtdYCB3aGVuIG5laXRoZXIgc291cmNlIGhhcyBlbnRyaWVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbGlzdChcbiAgY29uZmlndXJlZDogc3RyaW5nIHwgcmVhZG9ubHkgc3RyaW5nW10gfCB1bmRlZmluZWQgfCBudWxsLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICB0cmFuc2Zvcm0/OiAoZW50cnk6IHN0cmluZykgPT4gc3RyaW5nLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IHN0cmluZ1tdIHtcbiAgY29uc3QgZnJvbUNvbmZpZyA9IHN0cmluZ01vZHVsZS5wYXJzZUxpc3QoY29uZmlndXJlZCwgdHJhbnNmb3JtKTtcbiAgcmV0dXJuIGZyb21Db25maWcubGVuZ3RoID4gMFxuICAgID8gZnJvbUNvbmZpZ1xuICAgIDogc3RyaW5nTW9kdWxlLnBhcnNlTGlzdCh0ZXh0KGlucHV0LCBvcHRpb25zKSwgdHJhbnNmb3JtKTtcbn1cblxuZnVuY3Rpb24gdG9Qb3NpdGl2ZU51bWJlcih2YWx1ZTogdW5rbm93bik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHBhcnNlZCA9IG9iamVjdC50b051bWJlcih2YWx1ZSk7XG4gIHJldHVybiBwYXJzZWQgIT09IHVuZGVmaW5lZCAmJiBwYXJzZWQgPiAwID8gcGFyc2VkIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFRoZSBEYXRhYnJpY2tzIGJ1bmRsZSBvdXRwdXQgZm9yIGBjd2RgIC0gYGRhdGFicmlja3MgYnVuZGxlIHZhbGlkYXRlIC0tb3V0cHV0XG4gKiBqc29uYCBydW4gZnJvbSB0aGUgZGlyZWN0b3J5IGhvbGRpbmcgYGRhdGFicmlja3MueW1sYCwgd2l0aCB0aGUgY29uZmlnIGZpbGUnc1xuICogcGF0aC4gQSBub24temVybyB2YWxpZGF0aW9uIG1heSBzdGlsbCByZXR1cm4gcGFydGlhbCBKU09OIHdpdGggdXNhYmxlIEFwcFxuICogY29uZmlnLiBgdW5kZWZpbmVkYCB3aGVuIGJ1bmRsZSByZWFkcyBhcmUgZGlzYWJsZWQsIHRoaXMgaXMgbm90IGFuIEFwcEtpdFxuICogcHJvamVjdCwgdGhlIGJ1bmRsZSBkb2VzIG5vdCBkZXNjcmliZSBleGFjdGx5IG9uZSBhcHAgd2l0aCBgY29uZmlnLmVudmAsIHRoZXJlXG4gKiBpcyBubyBidW5kbGUsIG9yIHRoZSBDTEkgcHJvZHVjZXMgbm8gSlNPTi5cbiAqXG4gKiBUaGUgc3Bhd24gaXMgZ3VhcmRlZCBiZWNhdXNlIGl0IGlzIGV4cGVuc2l2ZSBhbmQgdXN1YWxseSBwb2ludGxlc3MuIEluIG9yZGVyOlxuICogYEBkYXRhYnJpY2tzL2FwcGtpdGAgbXVzdCBiZSBSRVNPTFZBQkxFIChubyBBcHBLaXQsIG5vIGJ1bmRsZSAtIGFuZCB0aGUgcHJvYmVcbiAqIG5ldmVyIGV2YWx1YXRlcyB0aGUgbW9kdWxlKTsgdGhlIGJ1bmRsZSBtdXN0IGRlc2NyaWJlIGV4YWN0bHkgT05FIGFwcCBjYXJyeWluZ1xuICogYGNvbmZpZy5lbnZgOyBhbmQgQXBwS2l0J3MgZXhlY3V0aW9uIGNvbnRleHQgbXVzdCBjb25maXJtIHRoaXMgcHJvY2VzcyBpcyB0aGF0XG4gKiBhcHAuIE9ubHkgdGhlIGNvbmZpcm1hdGlvbiBpcyByZW1lbWJlcmVkLCBzbyBhIGxvb2t1cCBkdXJpbmcgYm9vdCAtIGJlZm9yZSBhbnlcbiAqIGNvbnRleHQgZXhpc3RzIC0gc3RpbGwgcmVzb2x2ZXMgZnJvbSB0aGUgYnVuZGxlIGFuZCByZS1jb25maXJtcyBsYXRlci5cbiAqXG4gKiBDYWNoZWQgb25jZSBwZXIgcmVzb2x2ZWQgd29ya2luZy1kaXJlY3RvcnkgY29udGV4dCBhbmRcbiAqIGBEQVRBQlJJQ0tTX0NPTkZJR19QUk9GSUxFYCB0aHJvdWdoIHtAbGluayBjb250ZXh0LmNhY2hlZH0sIHNvIHJlcGVhdGVkXG4gKiBsb29rdXBzIGRvIG5vdCByZXJ1biB2YWxpZGF0aW9uIGFuZCBjaGFuZ2luZyBlaXRoZXIgY2Fubm90IHJldHVybiBhbm90aGVyXG4gKiBjb250ZXh0J3MgYnVuZGxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVuZGxlRmlsZShjd2Q/OiBzdHJpbmcgfCBudWxsKTogQ29uZmlnRmlsZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHByb2R1Y3Rpb24gPSBwcm9jZXNzLmVudi5OT0RFX0VOVj8udHJpbSgpLnRvTG93ZXJDYXNlKCkgPT09IFwicHJvZHVjdGlvblwiO1xuICBjb25zdCBvdmVycmlkZSA9IG9iamVjdC50b0Jvb2xlYW4ocHJvY2Vzcy5lbnZbQ09ORklHX0JVTkRMRV9LRVldKTtcbiAgaWYgKG92ZXJyaWRlID09PSBmYWxzZSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgLy8gQW4gZXhwbGljaXQgYHRydWVgIGlzIHRoZSBlc2NhcGUgaGF0Y2ggZm9yIGEgdG9vbCB0aGF0IHdhbnRzIHRoZSBidW5kbGVcbiAgLy8gd2l0aG91dCBiZWluZyB0aGUgYXBwIChgZGJ4YCBjb21tYW5kcywgdGVzdHMpLCBzbyBpdCBza2lwcyB0aGUgQXBwS2l0IGdhdGVcbiAgLy8gZW50aXJlbHkgLSBidXQgbm90IHRoZSBBcHAvcHJvZHVjdGlvbiBkZWZhdWx0cywgd2hpY2ggaXQgYWxzbyBvdmVycmlkZXMuXG4gIGlmIChvdmVycmlkZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHByb2R1Y3Rpb24gfHwgaXNEYXRhYnJpY2tzQXBwRW52KCkpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFhcHBLaXRJbnN0YWxsZWQoKSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBwcm9maWxlID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19DT05GSUdfUFJPRklMRSk7XG4gIGNvbnN0IGZpbGUgPSBjYWNoZWRDb25maWcoW1wiYnVuZGxlXCIsIHByb2ZpbGUgPz8gXCJcIl0sIGN3ZCwgKHJlc29sdmVkKSA9PlxuICAgIGxvYWRCdW5kbGVGaWxlKHJlc29sdmVkLCBwcm9maWxlKSxcbiAgKTtcbiAgaWYgKG92ZXJyaWRlICE9PSB1bmRlZmluZWQgfHwgZmlsZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmlsZTtcbiAgLy8gQWxyZWFkeSBjb25maXJtZWQ6IHRoaXMgcHJvY2VzcyBpcyB0aGUgYXBwLCBhbmQgdGhhdCBkb2VzIG5vdCBzdG9wIGJlaW5nXG4gIC8vIHRydWUsIHNvIHNraXAgcmUtZGVyaXZpbmcgdGhlIGdhdGUgb24gZXZlcnkgbG9va3VwLlxuICBpZiAoYXBwS2l0Q29udGV4dCkgcmV0dXJuIGZpbGU7XG4gIC8vIFRoZSBhcHAgbXVzdCBiZSB1bmFtYmlndW91cy4gYGJ1bmRsZUFwcGAgaXMgd2hhdCBkZWNpZGVzIFwiZXhhY3RseSBvbmUgYXBwXG4gIC8vIHdpdGggYGNvbmZpZy5lbnZgXCIsIHNvIGFuIGVtcHR5IG1hcCBJUyB0aGUgYW1iaWd1b3VzIG9yIGFwcC1sZXNzIGJ1bmRsZSBhbmRcbiAgLy8gbmVlZHMgbm8gc2VwYXJhdGUgY2hlY2suXG4gIGlmIChPYmplY3Qua2V5cyhidW5kbGVBcHAoZmlsZS5kYXRhKSkubGVuZ3RoID09PSAwKSByZXR1cm4gdW5kZWZpbmVkO1xuICBjb25maXJtQXBwS2l0Q29udGV4dCgpO1xuICByZXR1cm4gZmlsZTtcbn1cblxuLyoqXG4gKiBUaGUgc2luZ2xlIEFwcCdzIGxpdGVyYWwgYGNvbmZpZy5lbnZgIGVudHJpZXMsIGZsYXR0ZW5lZCB0byBgbmFtZSAtPiB2YWx1ZWAuXG4gKlxuICogQSBgdmFsdWVfZnJvbWAgZW50cnkgbmFtZXMgYSBidW5kbGUgcmVzb3VyY2Ugd2hvc2UgaWQgaXMga25vd24gYWZ0ZXJcbiAqIGRlcGxveW1lbnQsIGFuZCByZWFkaW5nIGl0IG5lZWRzIHRoZSByZXNvdXJjZSB2b2NhYnVsYXJ5IHRoaXMgbW9kdWxlXG4gKiBkZWxpYmVyYXRlbHkgZG9lcyBub3QgaGF2ZSAtIG5vZGUtYXBwa2l0IHJlc29sdmVzIHRob3NlIGFnYWluc3QgaXRzIGV4dGVuZGVkXG4gKiB7QGxpbmsgYnVuZGxlUmVzb3VyY2VTY2hlbWF9LiBBbiBgYXBwc2AgYmxvY2sgd2l0aCBtb3JlIHRoYW4gb25lIGFwcCBpc1xuICogYW1iaWd1b3VzIChub3RoaW5nIGhlcmUgc2F5cyB3aGljaCBhcHAgdGhpcyBwcm9jZXNzIGlzKSwgc28gaXQgeWllbGRzIG5vdGhpbmdcbiAqIHJhdGhlciB0aGFuIGEgZ3Vlc3MuXG4gKlxuICogTWVtb2l6ZWQgYWdhaW5zdCB0aGUgcGFyc2VkIGJ1bmRsZSBpdCBjYW1lIGZyb20sIGJlY2F1c2UgYm90aCB0aGUgZ2F0ZSBpblxuICoge0BsaW5rIGJ1bmRsZUZpbGV9IGFuZCB0aGUgbG9va3VwIGluIHtAbGluayByZWFkfSBhc2sgdGhlIHNhbWUgcXVlc3Rpb24gb2YgdGhlXG4gKiBzYW1lIGNhY2hlZCBvYmplY3QgLSB2YWxpZGF0aW5nIHRoYXQgcGF5bG9hZCB0d2ljZSBwZXIgbG9va3VwIHdvdWxkIGJlIHB1cmVcbiAqIHdhc3RlLiBBIGBXZWFrTWFwYCBrZWVwcyB0aGUgZW50cnkgYWxpdmUgZXhhY3RseSBhcyBsb25nIGFzIHRoZSBidW5kbGUgaXMuXG4gKi9cbmZ1bmN0aW9uIGJ1bmRsZUFwcChpbnB1dDogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBpZiAoIW9iamVjdC5pc1JlY29yZChpbnB1dCkpIHJldHVybiBidW5kbGVBcHBFbnRyaWVzKGlucHV0KTtcbiAgY29uc3QgY2FjaGVkID0gQlVORExFX0FQUF9DQUNIRS5nZXQoaW5wdXQpO1xuICBpZiAoY2FjaGVkKSByZXR1cm4gY2FjaGVkO1xuICBjb25zdCByZXN1bHQgPSBidW5kbGVBcHBFbnRyaWVzKGlucHV0KTtcbiAgQlVORExFX0FQUF9DQUNIRS5zZXQoaW5wdXQsIHJlc3VsdCk7XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKiB7QGxpbmsgYnVuZGxlQXBwfSB3aXRob3V0IHRoZSBtZW1vaXphdGlvbiwgc28gdGhlIGNhY2hlIGhhcyBvbmUgZmlsbGVyLiAqL1xuZnVuY3Rpb24gYnVuZGxlQXBwRW50cmllcyhpbnB1dDogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBwYXJzZWQgPSBidW5kbGVBcHBzU2NoZW1hLnNhZmVQYXJzZShpbnB1dCk7XG4gIGlmICghcGFyc2VkLnN1Y2Nlc3MpIHJldHVybiB7fTtcbiAgY29uc3QgYXBwcyA9IHBhcnNlZC5kYXRhLnJlc291cmNlcz8uYXBwcztcbiAgaWYgKCFhcHBzKSByZXR1cm4ge307XG4gIGNvbnN0IG5hbWVzID0gT2JqZWN0LmtleXMoYXBwcyk7XG4gIGlmIChuYW1lcy5sZW5ndGggIT09IDEpIHJldHVybiB7fTtcbiAgY29uc3QgZW50cmllcyA9IGFwcHNbbmFtZXNbMF0hXT8uY29uZmlnPy5lbnYgPz8gW107XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IGVudHJ5IG9mIGVudHJpZXMpIHtcbiAgICBpZiAoIWVudHJ5Lm5hbWUpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHZhbHVlID0gcmVzb2x2ZWRTdHJpbmcoZW50cnkudmFsdWUpO1xuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCkgcmVzdWx0W2VudHJ5Lm5hbWVdID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIGBAZGF0YWJyaWNrcy9hcHBraXRgIGNhbiBiZSBSRVNPTFZFRCBmcm9tIHRoaXMgcHJvY2VzcywgY2FjaGVkIGZvciBpdHNcbiAqIGxpZmV0aW1lLlxuICpcbiAqIFJlc29sdXRpb24sIG5vdCBpbXBvcnQ6IHRoaXMgYW5zd2VycyBcImlzIHRoaXMgYW4gQXBwS2l0IHByb2plY3RcIiB3aXRob3V0XG4gKiBldmFsdWF0aW5nIHRoZSBtb2R1bGUsIHNvIHRoZSBjaGVhcCBuZWdhdGl2ZSAoYSBwbGFpbiBsaWJyYXJ5IG9yIENMSSBjb25zdW1lclxuICogdGhhdCBuZXZlciBpbnN0YWxsZWQgdGhlIG9wdGlvbmFsIHBlZXIpIGNvc3RzIG9uZSBwYXRoIGxvb2t1cCBhbmQgbmV2ZXIgYm9vdHNcbiAqIEFwcEtpdCBhcyBhIHNpZGUgZWZmZWN0IG9mIHJlYWRpbmcgY29uZmlnLiBBIHJ1bnRpbWUgd2l0aCBubyBgY3JlYXRlUmVxdWlyZWBcbiAqIChhIGJyb3dzZXIgYnVuZGxlIHRoYXQgcmVhY2hlZCB0aGlzIE5vZGUtb25seSBtb2R1bGUgYW55d2F5KSByZXBvcnRzIGFic2VudC5cbiAqL1xuY29uc3QgYXBwS2l0SW5zdGFsbGVkID0gZnVuY3Rpb25Nb2R1bGUubWVtb2l6ZSgoKTogYm9vbGVhbiA9PiB7XG4gIHRyeSB7XG4gICAgLy8gSW5kaXJlY3Qgc3BlY2lmaWVyOiBhIGJ1bmRsZXIgbXVzdCBub3QgdHJ5IHRvIGZvbGxvdyBhbiBPUFRJT05BTCBwZWVyIHRoYXRcbiAgICAvLyBhIGJyb3dzZXIgYnVpbGQgaGFzIG5vIHdheSB0byByZXNvbHZlLlxuICAgIGNvbnN0IHNwZWNpZmllciA9IEFQUEtJVF9NT0RVTEU7XG4gICAgY3JlYXRlUmVxdWlyZShpbXBvcnQubWV0YS51cmwpLnJlc29sdmUoc3BlY2lmaWVyKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59KTtcblxuLyoqXG4gKiBBcHBLaXQncyBleGVjdXRpb24gY29udGV4dCBvbmNlIGl0IGV4aXN0cywgb3IgYHVuZGVmaW5lZGAuXG4gKlxuICogTGF6aWx5IGltcG9ydGVkIChhbmQgYEB2aXRlLWlnbm9yZWBkKSBiZWNhdXNlIGBAZGF0YWJyaWNrcy9hcHBraXRgIGlzIGFuXG4gKiBPUFRJT05BTCBwZWVyIHRoaXMgbW9kdWxlIG11c3QgbmV2ZXIgbWFrZSByZXF1aXJlZC4gVGhlIGltcG9ydCBpcyBvbmx5XG4gKiBhdHRlbXB0ZWQgb25jZSB7QGxpbmsgYXBwS2l0SW5zdGFsbGVkfSBzYXlzIHRoZXJlIGlzIHNvbWV0aGluZyB0byBpbXBvcnQsIGFuZCBhXG4gKiBmYWlsdXJlIHJlc29sdmVzIHRvIGB1bmRlZmluZWRgIHJhdGhlciB0aGFuIHJlamVjdGluZyAtIGEgbWlzc2luZyBwZWVyIGlzIHRoZVxuICogZXhwZWN0ZWQgcGF0aCwgbm90IGFuIGVycm9yLlxuICpcbiAqIGBnZXRFeGVjdXRpb25Db250ZXh0KClgIFRIUk9XUyB1bnRpbCBBcHBLaXQgaGFzIGJvb3RlZCwgc28gdGhlIGNhbGwgaXMgY2F1Z2h0XG4gKiBhbmQgb25seSBhIHJlYWwgY29udGV4dCBpcyByZXBvcnRlZC4gVGhlIG1vZHVsZSBoYW5kbGUgaXMgbWVtb2l6ZWQ7IHRoZVxuICogY29udGV4dCBsb29rdXAgaXMgbm90LCBzbyBhIGNhbGwgYmVmb3JlIGJvb3QgYW5zd2VycyBcIm5vdCB5ZXRcIiBhbmQgYSBsYXRlciBvbmVcbiAqIHN0aWxsIHNlZXMgdGhlIGNvbnRleHQuXG4gKi9cbmNvbnN0IGFwcEtpdE1vZHVsZSA9IGZ1bmN0aW9uTW9kdWxlLm1lbW9pemUoYXN5bmMgKCk6IFByb21pc2U8QXBwS2l0TW9kdWxlIHwgdW5kZWZpbmVkPiA9PiB7XG4gIGlmICghYXBwS2l0SW5zdGFsbGVkKCkpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHNwZWNpZmllciA9IEFQUEtJVF9NT0RVTEU7XG4gIHJldHVybiAoYXdhaXQgaW1wb3J0KC8qIEB2aXRlLWlnbm9yZSAqLyBzcGVjaWZpZXIpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCkpIGFzXG4gICAgQXBwS2l0TW9kdWxlIHwgdW5kZWZpbmVkO1xufSk7XG5cbi8qKlxuICogTGF0Y2gge0BsaW5rIGFwcEtpdENvbnRleHR9IG9uY2UgQXBwS2l0J3MgZXhlY3V0aW9uIGNvbnRleHQgZXhpc3RzLlxuICpcbiAqIEZpcmUtYW5kLWZvcmdldCwgYmVjYXVzZSB0aGUgY2FsbGVyIGlzIGEgU1lOQ0hST05PVVMgbG9va3VwIGFuZCB0aGUgY2hlY2tcbiAqIG5lZWRzIGEgbGF6eSBpbXBvcnQuIFRoZSBhZmZpcm1hdGl2ZSBpcyBhbGwgdGhhdCBpcyBzdG9yZWQ6IEFwcEtpdCdzIGNvbnRleHRcbiAqIGRvZXMgbm90IGV4aXN0IHVudGlsIGl0IGJvb3RzLCBhbmQgYGdldEV4ZWN1dGlvbkNvbnRleHQoKWAgdGhyb3dzIHVudGlsIHRoZW4sXG4gKiBzbyByZW1lbWJlcmluZyBhIG5lZ2F0aXZlIHdvdWxkIHBlcm1hbmVudGx5IGRpc2FibGUgdGhlIGJ1bmRsZSBmb3IgYSBwcm9jZXNzXG4gKiB0aGF0IGlzIHNlY29uZHMgYXdheSBmcm9tIGhhdmluZyBvbmUuIEV2ZXJ5IGNhbGwgYmVmb3JlIHRoZSBsYXRjaCBjbG9zZXNcbiAqIHJlLWF0dGVtcHRzLCB3aGljaCBpcyB3aGF0IG1ha2VzIFwibm90IGF2YWlsYWJsZSB5ZXRcIiByZXRyeSByYXRoZXIgdGhhbiBzdGljay5cbiAqL1xuZnVuY3Rpb24gY29uZmlybUFwcEtpdENvbnRleHQoKTogdm9pZCB7XG4gIHZvaWQgYXBwS2l0TW9kdWxlKClcbiAgICAudGhlbigoYXBwa2l0KSA9PiB7XG4gICAgICBpZiAoIWFwcGtpdCkgcmV0dXJuO1xuICAgICAgdHJ5IHtcbiAgICAgICAgaWYgKGFwcGtpdC5nZXRFeGVjdXRpb25Db250ZXh0KCk/LmNsaWVudCkgYXBwS2l0Q29udGV4dCA9IHRydWU7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLy8gQXBwS2l0IGhhcyBub3QgYm9vdGVkIHlldDsgYSBsYXRlciBjYWxsIHJlLWNoZWNrcy5cbiAgICAgIH1cbiAgICB9KVxuICAgIC5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xufVxuXG4vKiogQSBub24tZW1wdHkgYnVuZGxlIHZhbHVlIHdpdGggZXZlcnkgYCR7Li4ufWAgaW50ZXJwb2xhdGlvbiByZXNvbHZlZC4gKi9cbmZ1bmN0aW9uIHJlc29sdmVkU3RyaW5nKHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHBhcnNlZCA9IGJ1bmRsZVZhbHVlLnNhZmVQYXJzZSh2YWx1ZSk7XG4gIHJldHVybiBwYXJzZWQuc3VjY2VzcyA/IHBhcnNlZC5kYXRhIDogbnVsbDtcbn1cblxuLyoqIFBhcnNlZCBgLmVudmAgZm9yIGBjd2RgLCBvciBge31gLiBSZWFkIG9uY2UgcGVyIHJlc29sdmVkIGNvbnRleHQuICovXG5mdW5jdGlvbiBkb3RlbnYoY3dkPzogc3RyaW5nIHwgbnVsbCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBpZiAoIWZpbGVTb3VyY2VFbmFibGVkKENPTkZJR19ET1RFTlZfS0VZKSkgcmV0dXJuIHt9O1xuICBjb25zdCBlbnZpcm9ubWVudHMgPSBub2RlRW52TmFtZXMocHJvY2Vzcy5lbnYuTk9ERV9FTlYpO1xuICByZXR1cm4gY2FjaGVkQ29uZmlnKFtcImRvdGVudlwiLCAuLi5lbnZpcm9ubWVudHNdLCBjd2QsIChyZXNvbHZlZCkgPT5cbiAgICBsb2FkRG90ZW52KHJlc29sdmVkLCBlbnZpcm9ubWVudHMpLFxuICApO1xufVxuXG4vKiogQ2FjaGUgZXZlcnkgdGFyZ2V0IGRpcmVjdG9yeSBzZXBhcmF0ZWx5IHdpdGhpbiB0aGUgYWN0aXZlIHByb2Nlc3MgY29udGV4dC4gKi9cbmZ1bmN0aW9uIGNhY2hlZENvbmZpZzxUPihcbiAgbmFtZTogcmVhZG9ubHkgc3RyaW5nW10sXG4gIGN3ZDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgbG9hZGVyOiAocmVzb2x2ZWQ6IHN0cmluZykgPT4gVCxcbik6IFQge1xuICBjb25zdCBhY3RpdmUgPSBjb250ZXh0LmdldENvbnRleHQoKSA/PyBcIlwiO1xuICBjb25zdCByZXNvbHZlZCA9IHJlc29sdmUoY3dkID8/IFwiLlwiKTtcbiAgcmV0dXJuIGNvbnRleHQuY2FjaGVkKFtcImNvbmZpZ1wiLCBhY3RpdmUsIHJlc29sdmVkLCAuLi5uYW1lXSwgKCkgPT4gbG9hZGVyKHJlc29sdmVkKSk7XG59XG5cbi8qKlxuICogTWFwcyBmb3Igb25lIHNvdXJjZSBpbiBwcmVjZWRlbmNlIG9yZGVyLiBCdW5kbGUgQXBwIGNvbmZpZyBhbmQgcm9vdCB2YXJpYWJsZXNcbiAqIHN0YXkgc2VwYXJhdGUgc28gYSBmaXJzdC1tYXRjaCBsb29rdXAgZG9lcyBub3QgcGFyc2UgdmFyaWFibGVzIGFmdGVyIGFuIEFwcFxuICogdmFsdWUgcmVzb2x2ZXMuXG4gKi9cbmZ1bmN0aW9uIHJlYWQoXG4gIHNvdXJjZTogQ29uZmlnU291cmNlLFxuICBjd2Q/OiBzdHJpbmcsXG4pOiBvYmplY3QuU2VxdWVuY2U8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPj4ge1xuICByZXR1cm4gb2JqZWN0LnNlcXVlbmNlKHtcbiAgICAqW1N5bWJvbC5pdGVyYXRvcl0oKTogR2VuZXJhdG9yPFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4+IHtcbiAgICAgIHN3aXRjaCAoc291cmNlKSB7XG4gICAgICAgIGNhc2UgXCJlbnZcIjpcbiAgICAgICAgICB5aWVsZCBwcm9jZXNzLmVudjtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImRvdGVudlwiOlxuICAgICAgICAgIHlpZWxkIGRvdGVudihjd2QpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFwiYnVuZGxlXCI6IHtcbiAgICAgICAgICBjb25zdCBidW5kbGUgPSBidW5kbGVGaWxlKGN3ZCk7XG4gICAgICAgICAgaWYgKGJ1bmRsZSkgeWllbGQgYnVuZGxlQXBwKGJ1bmRsZS5kYXRhKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIExvY2F0ZSBgbmFtZXNgIGZyb20gYGN3ZGAgb3V0d2FyZC4gYGN3ZGAgaXRzZWxmIGlzIGNoZWNrZWQgYmVmb3JlIHRoZVxuICogZGlzY292ZXJlZCBwcm9qZWN0IHJvb3RzIHNvIGEgcGFja2FnZS1sb2NhbCBmaWxlIHdpbnMgb3ZlciB0aGUgd29ya3NwYWNlJ3MuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDb25maWdGaWxlKGN3ZDogc3RyaW5nLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBzdGFydCA9IHJlc29sdmUoY3dkKTtcbiAgY29uc3Qgcm9vdCA9IHJlc29sdmVQcm9qZWN0Um9vdChzdGFydCk7XG4gIGNvbnN0IHBhdGhGcm9tUm9vdCA9IHJvb3QgPyByZWxhdGl2ZShyb290LCBzdGFydCkgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGJvdW5kYXJ5ID1cbiAgICByb290ICYmXG4gICAgcGF0aEZyb21Sb290ICE9PSB1bmRlZmluZWQgJiZcbiAgICAhaXNBYnNvbHV0ZShwYXRoRnJvbVJvb3QpICYmXG4gICAgcGF0aEZyb21Sb290ICE9PSBcIi4uXCIgJiZcbiAgICAhcGF0aEZyb21Sb290LnN0YXJ0c1dpdGgoYC4uJHtzZXB9YClcbiAgICAgID8gcm9vdFxuICAgICAgOiB1bmRlZmluZWQ7XG4gIGZvciAobGV0IGRpciA9IHN0YXJ0OyA7IGRpciA9IGRpcm5hbWUoZGlyKSkge1xuICAgIGZvciAoY29uc3QgbmFtZSBvZiBuYW1lcykge1xuICAgICAgY29uc3QgcGF0aCA9IHJlc29sdmUoZGlyLCBuYW1lKTtcbiAgICAgIGlmIChzdGF0U3luYyhwYXRoKT8uaXNGaWxlKCkpIHJldHVybiBwYXRoO1xuICAgIH1cbiAgICBpZiAoYm91bmRhcnkgPT09IHVuZGVmaW5lZCB8fCBkaXIgPT09IGJvdW5kYXJ5KSBicmVhaztcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKiogQSByZWNvZ25pemVkIHNvdXJjZSBvdmVycmlkZSwgZWxzZSB0aGUgY2FsbGVyJ3MgYXV0b21hdGljIGRlZmF1bHQuICovXG5mdW5jdGlvbiBmaWxlU291cmNlRW5hYmxlZChrZXk6IHN0cmluZywgZmFsbGJhY2s6IGJvb2xlYW4gPSAhaXNEYXRhYnJpY2tzQXBwRW52KCkpOiBib29sZWFuIHtcbiAgcmV0dXJuIG9iamVjdC50b0Jvb2xlYW4ocHJvY2Vzcy5lbnZba2V5XSkgPz8gZmFsbGJhY2s7XG59XG5cbmZ1bmN0aW9uIGxvYWREb3RlbnYoXG4gIGN3ZDogc3RyaW5nLFxuICBlbnZpcm9ubWVudHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IG5hbWVzID0gWy4uLmVudmlyb25tZW50cy5tYXAoKG5hbWUpID0+IGAke0RPVEVOVl9GSUxFX05BTUV9LiR7bmFtZX1gKSwgRE9URU5WX0ZJTEVfTkFNRV07XG4gIGNvbnN0IHBhdGggPSBmaW5kQ29uZmlnRmlsZShjd2QsIG5hbWVzKTtcbiAgaWYgKCFwYXRoKSByZXR1cm4ge307XG4gIHRyeSB7XG4gICAgcmV0dXJuIHBhcnNlRW52KHJlYWRGaWxlU3luYyhwYXRoLCBcInV0ZjhcIikpO1xuICB9IGNhdGNoIHtcbiAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byByZWFkIGRvdGVudiBmaWxlXCIsIHsgcGF0aCB9KTtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9hZEJ1bmRsZUZpbGUoY3dkOiBzdHJpbmcsIHByb2ZpbGU6IHN0cmluZyB8IG51bGwpOiBDb25maWdGaWxlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGF0aCA9IGZpbmRDb25maWdGaWxlKGN3ZCwgQlVORExFX0ZJTEVfTkFNRVMpO1xuICBpZiAoIXBhdGgpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgXCJidW5kbGVcIixcbiAgICBcInZhbGlkYXRlXCIsXG4gICAgXCItLW91dHB1dFwiLFxuICAgIFwianNvblwiLFxuICAgIC4uLihwcm9maWxlID09PSBudWxsID8gW10gOiBbXCItLXByb2ZpbGVcIiwgcHJvZmlsZV0pLFxuICBdO1xuICBjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXCJkYXRhYnJpY2tzXCIsIGFyZ3MsIHtcbiAgICBjd2Q6IHJlc29sdmUocGF0aCwgXCIuLlwiKSxcbiAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgc3RkaW86IFtcImlnbm9yZVwiLCBcInBpcGVcIiwgXCJwaXBlXCJdLFxuICB9KTtcbiAgY29uc3Qgb3V0cHV0ID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocmVzdWx0LnN0ZG91dCk7XG4gIGNvbnN0IGVycm9yID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocmVzdWx0LnN0ZGVycik7XG4gIGlmIChvdXRwdXQgPT09IG51bGwpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJidW5kbGUgdmFsaWRhdGUgcHJvZHVjZWQgbm8gSlNPTlwiLCB7IHBhdGgsIHN0YXR1czogcmVzdWx0LnN0YXR1cywgZXJyb3IgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBkYXRhID0ganNvbi5wYXJzZVJlY29yZChvdXRwdXQpO1xuICBpZiAoIWRhdGEpIHtcbiAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byBwYXJzZSBidW5kbGUgdmFsaWRhdGUgb3V0cHV0XCIsIHsgcGF0aCwgc3RhdHVzOiByZXN1bHQuc3RhdHVzIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcbiAgICBsb2dnZXIuZGVidWcoXCJ1c2luZyBwYXJ0aWFsIGJ1bmRsZSBvdXRwdXRcIiwgeyBwYXRoLCBzdGF0dXM6IHJlc3VsdC5zdGF0dXMsIGVycm9yIH0pO1xuICB9XG4gIHJldHVybiB7IHBhdGgsIGRhdGEgfTtcbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -18,12 +18,16 @@
|
|
|
18
18
|
"projen": "projen"
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
|
+
"@databricks/appkit": "^0.43.0",
|
|
21
22
|
"@types/bun": "^1.3.14",
|
|
22
23
|
"@types/node": "^24.6.0",
|
|
23
24
|
"typescript": "^5.9.3"
|
|
24
25
|
},
|
|
26
|
+
"peerDependencies": {
|
|
27
|
+
"@databricks/appkit": "^0.43.0"
|
|
28
|
+
},
|
|
25
29
|
"dependencies": {
|
|
26
|
-
"@dbx-tools/shared-core": "0.6.
|
|
30
|
+
"@dbx-tools/shared-core": "0.6.88",
|
|
27
31
|
"extract-zip": "^2.0.1",
|
|
28
32
|
"tar": "^7.5.22",
|
|
29
33
|
"yaml": "^2.9.0",
|
|
@@ -43,7 +47,7 @@
|
|
|
43
47
|
"./package.json": "./package.json"
|
|
44
48
|
}
|
|
45
49
|
},
|
|
46
|
-
"version": "0.6.
|
|
50
|
+
"version": "0.6.88",
|
|
47
51
|
"types": "./lib/index.d.ts",
|
|
48
52
|
"type": "module",
|
|
49
53
|
"exports": {
|
|
@@ -58,6 +62,11 @@
|
|
|
58
62
|
"src",
|
|
59
63
|
"lib"
|
|
60
64
|
],
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"@databricks/appkit": {
|
|
67
|
+
"optional": true
|
|
68
|
+
}
|
|
69
|
+
},
|
|
61
70
|
"dbxToolsConfig": {
|
|
62
71
|
"tags": [
|
|
63
72
|
"node"
|
package/src/config.ts
CHANGED
|
@@ -20,6 +20,29 @@
|
|
|
20
20
|
* CLI is not on the image. Boolean environment overrides can force either file
|
|
21
21
|
* source on or off when a tool needs different behavior.
|
|
22
22
|
*
|
|
23
|
+
* The bundle is gated on this being an AppKit project at all. `databricks bundle
|
|
24
|
+
* validate` is a process spawn measured in seconds, and a plain library or CLI
|
|
25
|
+
* consumer has no bundle to find, so the gate runs in three steps before the
|
|
26
|
+
* spawn is allowed - see {@link bundleFile}:
|
|
27
|
+
*
|
|
28
|
+
* 1. `@databricks/appkit` is resolved WITHOUT evaluating it. It is an optional
|
|
29
|
+
* peer, so a consumer that never installed it is not an AppKit project and
|
|
30
|
+
* the bundle is never loaded. The probe is cached, so this costs one
|
|
31
|
+
* resolution for the life of the process.
|
|
32
|
+
* 2. The bundle is read (once per context) and must describe EXACTLY ONE app
|
|
33
|
+
* with `config.env`. Nothing here says which of several apps this process
|
|
34
|
+
* is, so an ambiguous bundle contributes nothing rather than a guess.
|
|
35
|
+
* 3. AppKit's execution context confirms this process really is that app. The
|
|
36
|
+
* context does not exist until AppKit boots and `getExecutionContext()`
|
|
37
|
+
* THROWS until then, so the probe is caught and only the affirmative is
|
|
38
|
+
* remembered - a lookup before boot still resolves, and re-confirms later
|
|
39
|
+
* once the context is available.
|
|
40
|
+
*
|
|
41
|
+
* Only the single app's `config.env` is consulted. Root bundle `variables` are
|
|
42
|
+
* not: they are authoring inputs for the bundle itself (interpolated into
|
|
43
|
+
* targets, resources, and paths), so treating one as a process setting resolves
|
|
44
|
+
* names the deployed app never sees.
|
|
45
|
+
*
|
|
23
46
|
* Node-only (`child_process`, `fs`, `process`).
|
|
24
47
|
*
|
|
25
48
|
* @module
|
|
@@ -27,9 +50,17 @@
|
|
|
27
50
|
|
|
28
51
|
import { spawnSync } from "node:child_process";
|
|
29
52
|
import { readFileSync } from "node:fs";
|
|
53
|
+
import { createRequire } from "node:module";
|
|
30
54
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
31
55
|
import { parseEnv } from "node:util";
|
|
32
|
-
import {
|
|
56
|
+
import {
|
|
57
|
+
context,
|
|
58
|
+
functionModule,
|
|
59
|
+
json,
|
|
60
|
+
log,
|
|
61
|
+
object,
|
|
62
|
+
string as stringModule,
|
|
63
|
+
} from "@dbx-tools/shared-core";
|
|
33
64
|
import { z } from "zod";
|
|
34
65
|
import { statSync } from "./file.ts";
|
|
35
66
|
import { root as resolveProjectRoot } from "./project.ts";
|
|
@@ -88,6 +119,32 @@ export const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
|
|
|
88
119
|
/** Boolean environment override for Databricks bundle reads. */
|
|
89
120
|
export const CONFIG_BUNDLE_KEY = "DBX_TOOLS_CONFIG_BUNDLE";
|
|
90
121
|
|
|
122
|
+
/**
|
|
123
|
+
* The OPTIONAL AppKit peer whose presence marks this as a Databricks App
|
|
124
|
+
* project. Held as a constant so the resolve probe and the lazy import name it
|
|
125
|
+
* once, and so neither site carries a literal a bundler would try to follow.
|
|
126
|
+
*/
|
|
127
|
+
const APPKIT_MODULE = "@databricks/appkit";
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The one thing this module needs from AppKit: whether a real execution context
|
|
131
|
+
* is active. Typed structurally so an OPTIONAL peer never becomes a type
|
|
132
|
+
* dependency, and `client` is `unknown` because its presence is all that is read.
|
|
133
|
+
*/
|
|
134
|
+
type AppKitModule = {
|
|
135
|
+
getExecutionContext(): { client?: unknown } | undefined;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Whether AppKit's execution context has EVER been observed. Latching is the
|
|
140
|
+
* point: a context confirms this process is the bundle's app, and that fact does
|
|
141
|
+
* not stop being true when a later lookup happens outside a request scope.
|
|
142
|
+
*/
|
|
143
|
+
let appKitContext = false;
|
|
144
|
+
|
|
145
|
+
/** Flattened App `config.env` per parsed bundle - see {@link bundleApp}. */
|
|
146
|
+
const BUNDLE_APP_CACHE = new WeakMap<object, Record<string, string>>();
|
|
147
|
+
|
|
91
148
|
/** Exact process-environment lookup for callers that do not read local config files. */
|
|
92
149
|
export const ENV_ONLY = { scope: [] as const, sources: "env" as const };
|
|
93
150
|
|
|
@@ -114,11 +171,6 @@ export const bundleEnvEntrySchema = z.object({
|
|
|
114
171
|
value_from: bundleValue.optional(),
|
|
115
172
|
});
|
|
116
173
|
|
|
117
|
-
const bundleVariableSchema = z.object({
|
|
118
|
-
default: z.string().optional(),
|
|
119
|
-
value: z.string().optional(),
|
|
120
|
-
});
|
|
121
|
-
|
|
122
174
|
export const bundleAppSchema = z.object({
|
|
123
175
|
name: bundleValue.optional(),
|
|
124
176
|
source_code_path: z.string().optional(),
|
|
@@ -130,10 +182,6 @@ const bundleAppsSchema = z.object({
|
|
|
130
182
|
resources: z.object({ apps: z.record(z.string(), bundleAppSchema).optional() }).optional(),
|
|
131
183
|
});
|
|
132
184
|
|
|
133
|
-
const bundleVariablesSchema = z.object({
|
|
134
|
-
variables: z.record(z.string(), bundleVariableSchema).optional(),
|
|
135
|
-
});
|
|
136
|
-
|
|
137
185
|
/**
|
|
138
186
|
* Detect a Databricks App runtime from its required name, host, and port.
|
|
139
187
|
*
|
|
@@ -338,9 +386,17 @@ function toPositiveNumber(value: unknown): number | undefined {
|
|
|
338
386
|
/**
|
|
339
387
|
* The Databricks bundle output for `cwd` - `databricks bundle validate --output
|
|
340
388
|
* json` run from the directory holding `databricks.yml`, with the config file's
|
|
341
|
-
* path. A non-zero validation may still return partial JSON with usable
|
|
342
|
-
*
|
|
343
|
-
* the
|
|
389
|
+
* path. A non-zero validation may still return partial JSON with usable App
|
|
390
|
+
* config. `undefined` when bundle reads are disabled, this is not an AppKit
|
|
391
|
+
* project, the bundle does not describe exactly one app with `config.env`, there
|
|
392
|
+
* is no bundle, or the CLI produces no JSON.
|
|
393
|
+
*
|
|
394
|
+
* The spawn is guarded because it is expensive and usually pointless. In order:
|
|
395
|
+
* `@databricks/appkit` must be RESOLVABLE (no AppKit, no bundle - and the probe
|
|
396
|
+
* never evaluates the module); the bundle must describe exactly ONE app carrying
|
|
397
|
+
* `config.env`; and AppKit's execution context must confirm this process is that
|
|
398
|
+
* app. Only the confirmation is remembered, so a lookup during boot - before any
|
|
399
|
+
* context exists - still resolves from the bundle and re-confirms later.
|
|
344
400
|
*
|
|
345
401
|
* Cached once per resolved working-directory context and
|
|
346
402
|
* `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
|
|
@@ -349,11 +405,29 @@ function toPositiveNumber(value: unknown): number | undefined {
|
|
|
349
405
|
*/
|
|
350
406
|
export function bundleFile(cwd?: string | null): ConfigFile | undefined {
|
|
351
407
|
const production = process.env.NODE_ENV?.trim().toLowerCase() === "production";
|
|
352
|
-
|
|
408
|
+
const override = object.toBoolean(process.env[CONFIG_BUNDLE_KEY]);
|
|
409
|
+
if (override === false) return undefined;
|
|
410
|
+
// An explicit `true` is the escape hatch for a tool that wants the bundle
|
|
411
|
+
// without being the app (`dbx` commands, tests), so it skips the AppKit gate
|
|
412
|
+
// entirely - but not the App/production defaults, which it also overrides.
|
|
413
|
+
if (override === undefined) {
|
|
414
|
+
if (production || isDatabricksAppEnv()) return undefined;
|
|
415
|
+
if (!appKitInstalled()) return undefined;
|
|
416
|
+
}
|
|
353
417
|
const profile = stringModule.trimToNull(process.env.DATABRICKS_CONFIG_PROFILE);
|
|
354
|
-
|
|
418
|
+
const file = cachedConfig(["bundle", profile ?? ""], cwd, (resolved) =>
|
|
355
419
|
loadBundleFile(resolved, profile),
|
|
356
420
|
);
|
|
421
|
+
if (override !== undefined || file === undefined) return file;
|
|
422
|
+
// Already confirmed: this process is the app, and that does not stop being
|
|
423
|
+
// true, so skip re-deriving the gate on every lookup.
|
|
424
|
+
if (appKitContext) return file;
|
|
425
|
+
// The app must be unambiguous. `bundleApp` is what decides "exactly one app
|
|
426
|
+
// with `config.env`", so an empty map IS the ambiguous or app-less bundle and
|
|
427
|
+
// needs no separate check.
|
|
428
|
+
if (Object.keys(bundleApp(file.data)).length === 0) return undefined;
|
|
429
|
+
confirmAppKitContext();
|
|
430
|
+
return file;
|
|
357
431
|
}
|
|
358
432
|
|
|
359
433
|
/**
|
|
@@ -365,8 +439,23 @@ export function bundleFile(cwd?: string | null): ConfigFile | undefined {
|
|
|
365
439
|
* {@link bundleResourceSchema}. An `apps` block with more than one app is
|
|
366
440
|
* ambiguous (nothing here says which app this process is), so it yields nothing
|
|
367
441
|
* rather than a guess.
|
|
442
|
+
*
|
|
443
|
+
* Memoized against the parsed bundle it came from, because both the gate in
|
|
444
|
+
* {@link bundleFile} and the lookup in {@link read} ask the same question of the
|
|
445
|
+
* same cached object - validating that payload twice per lookup would be pure
|
|
446
|
+
* waste. A `WeakMap` keeps the entry alive exactly as long as the bundle is.
|
|
368
447
|
*/
|
|
369
448
|
function bundleApp(input: unknown): Record<string, string> {
|
|
449
|
+
if (!object.isRecord(input)) return bundleAppEntries(input);
|
|
450
|
+
const cached = BUNDLE_APP_CACHE.get(input);
|
|
451
|
+
if (cached) return cached;
|
|
452
|
+
const result = bundleAppEntries(input);
|
|
453
|
+
BUNDLE_APP_CACHE.set(input, result);
|
|
454
|
+
return result;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/** {@link bundleApp} without the memoization, so the cache has one filler. */
|
|
458
|
+
function bundleAppEntries(input: unknown): Record<string, string> {
|
|
370
459
|
const parsed = bundleAppsSchema.safeParse(input);
|
|
371
460
|
if (!parsed.success) return {};
|
|
372
461
|
const apps = parsed.data.resources?.apps;
|
|
@@ -384,23 +473,69 @@ function bundleApp(input: unknown): Record<string, string> {
|
|
|
384
473
|
}
|
|
385
474
|
|
|
386
475
|
/**
|
|
387
|
-
*
|
|
476
|
+
* Whether `@databricks/appkit` can be RESOLVED from this process, cached for its
|
|
477
|
+
* lifetime.
|
|
388
478
|
*
|
|
389
|
-
*
|
|
390
|
-
*
|
|
391
|
-
*
|
|
392
|
-
*
|
|
479
|
+
* Resolution, not import: this answers "is this an AppKit project" without
|
|
480
|
+
* evaluating the module, so the cheap negative (a plain library or CLI consumer
|
|
481
|
+
* that never installed the optional peer) costs one path lookup and never boots
|
|
482
|
+
* AppKit as a side effect of reading config. A runtime with no `createRequire`
|
|
483
|
+
* (a browser bundle that reached this Node-only module anyway) reports absent.
|
|
393
484
|
*/
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
485
|
+
const appKitInstalled = functionModule.memoize((): boolean => {
|
|
486
|
+
try {
|
|
487
|
+
// Indirect specifier: a bundler must not try to follow an OPTIONAL peer that
|
|
488
|
+
// a browser build has no way to resolve.
|
|
489
|
+
const specifier = APPKIT_MODULE;
|
|
490
|
+
createRequire(import.meta.url).resolve(specifier);
|
|
491
|
+
return true;
|
|
492
|
+
} catch {
|
|
493
|
+
return false;
|
|
402
494
|
}
|
|
403
|
-
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* AppKit's execution context once it exists, or `undefined`.
|
|
499
|
+
*
|
|
500
|
+
* Lazily imported (and `@vite-ignore`d) because `@databricks/appkit` is an
|
|
501
|
+
* OPTIONAL peer this module must never make required. The import is only
|
|
502
|
+
* attempted once {@link appKitInstalled} says there is something to import, and a
|
|
503
|
+
* failure resolves to `undefined` rather than rejecting - a missing peer is the
|
|
504
|
+
* expected path, not an error.
|
|
505
|
+
*
|
|
506
|
+
* `getExecutionContext()` THROWS until AppKit has booted, so the call is caught
|
|
507
|
+
* and only a real context is reported. The module handle is memoized; the
|
|
508
|
+
* context lookup is not, so a call before boot answers "not yet" and a later one
|
|
509
|
+
* still sees the context.
|
|
510
|
+
*/
|
|
511
|
+
const appKitModule = functionModule.memoize(async (): Promise<AppKitModule | undefined> => {
|
|
512
|
+
if (!appKitInstalled()) return undefined;
|
|
513
|
+
const specifier = APPKIT_MODULE;
|
|
514
|
+
return (await import(/* @vite-ignore */ specifier).catch(() => undefined)) as
|
|
515
|
+
AppKitModule | undefined;
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
/**
|
|
519
|
+
* Latch {@link appKitContext} once AppKit's execution context exists.
|
|
520
|
+
*
|
|
521
|
+
* Fire-and-forget, because the caller is a SYNCHRONOUS lookup and the check
|
|
522
|
+
* needs a lazy import. The affirmative is all that is stored: AppKit's context
|
|
523
|
+
* does not exist until it boots, and `getExecutionContext()` throws until then,
|
|
524
|
+
* so remembering a negative would permanently disable the bundle for a process
|
|
525
|
+
* that is seconds away from having one. Every call before the latch closes
|
|
526
|
+
* re-attempts, which is what makes "not available yet" retry rather than stick.
|
|
527
|
+
*/
|
|
528
|
+
function confirmAppKitContext(): void {
|
|
529
|
+
void appKitModule()
|
|
530
|
+
.then((appkit) => {
|
|
531
|
+
if (!appkit) return;
|
|
532
|
+
try {
|
|
533
|
+
if (appkit.getExecutionContext()?.client) appKitContext = true;
|
|
534
|
+
} catch {
|
|
535
|
+
// AppKit has not booted yet; a later call re-checks.
|
|
536
|
+
}
|
|
537
|
+
})
|
|
538
|
+
.catch(() => undefined);
|
|
404
539
|
}
|
|
405
540
|
|
|
406
541
|
/** A non-empty bundle value with every `${...}` interpolation resolved. */
|
|
@@ -449,10 +584,7 @@ function read(
|
|
|
449
584
|
break;
|
|
450
585
|
case "bundle": {
|
|
451
586
|
const bundle = bundleFile(cwd);
|
|
452
|
-
if (bundle)
|
|
453
|
-
yield bundleApp(bundle.data);
|
|
454
|
-
yield bundleVariables(bundle.data);
|
|
455
|
-
}
|
|
587
|
+
if (bundle) yield bundleApp(bundle.data);
|
|
456
588
|
break;
|
|
457
589
|
}
|
|
458
590
|
}
|