@dbx-tools/core 0.6.85 → 0.6.87
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 +72 -4
- package/index.ts +2 -2
- package/lib/index.d.ts +2 -2
- package/lib/index.js +2 -2
- package/lib/src/config.d.ts +55 -12
- package/lib/src/config.js +200 -41
- package/package.json +11 -2
- package/src/config.ts +213 -49
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# @dbx-tools/core
|
|
2
2
|
|
|
3
|
-
Node-only core helpers for binary installation, process
|
|
4
|
-
discovery.
|
|
3
|
+
Node-only core helpers for layered configuration, binary installation, process
|
|
4
|
+
execution, locking, and project discovery.
|
|
5
5
|
|
|
6
6
|
Import this package when code needs `node:child_process`, `node:fs`, or
|
|
7
7
|
`node:path`. Browser-safe utilities live in
|
|
@@ -16,10 +16,12 @@ 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
|
+
- Cross-process file locks with a Bun `flock(2)` fast path and a portable,
|
|
24
|
+
stale-reclaiming lock-directory fallback.
|
|
23
25
|
- Keyed mutual exclusion across the main thread and its worker threads.
|
|
24
26
|
|
|
25
27
|
## Install A Binary
|
|
@@ -95,6 +97,45 @@ produce names such as `DBX_TOOLS_TUNNEL_PUBLIC_DOMAIN`, then
|
|
|
95
97
|
are checked before `.env` when `NODE_ENV=production`; development uses
|
|
96
98
|
`.env.development` and `.env.dev`.
|
|
97
99
|
|
|
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`, 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
|
+
|
|
122
|
+
Deployed Apps skip dotenv and bundle lookup after `isDatabricksAppEnv()`
|
|
123
|
+
recognizes the required App name, HTTP(S) host, and valid port. Set
|
|
124
|
+
`DBX_TOOLS_DATABRICKS_APP_ENV=true` or `false` to force that result; unrecognized
|
|
125
|
+
values leave automatic detection in place.
|
|
126
|
+
|
|
127
|
+
`DBX_TOOLS_CONFIG_DOTENV` and `DBX_TOOLS_CONFIG_BUNDLE` independently force
|
|
128
|
+
those file sources on or off. A recognized boolean takes precedence over App
|
|
129
|
+
runtime detection, so `true` can enable a local source inside an App and `false`
|
|
130
|
+
can suppress it during local development. Absent or unrecognized values keep
|
|
131
|
+
the default: read files outside an App and skip them inside one. Bundle reads
|
|
132
|
+
also default off when `NODE_ENV=production`; set
|
|
133
|
+
`DBX_TOOLS_CONFIG_BUNDLE=true` to opt into bundle validation there.
|
|
134
|
+
|
|
135
|
+
Use `config.string()`, `boolean()`, `positiveNumber()`, `positiveInt()`, and
|
|
136
|
+
`list()` to normalize typed options and text-based configuration through one
|
|
137
|
+
rule. `config.ENV_ONLY` disables file fallbacks for exact environment reads.
|
|
138
|
+
|
|
98
139
|
## Run Commands
|
|
99
140
|
|
|
100
141
|
```ts
|
|
@@ -188,6 +229,28 @@ deployment, use
|
|
|
188
229
|
[`@dbx-tools/postgres`](../postgres)'s `withAdvisoryLock`, which puts the arbiter
|
|
189
230
|
in PostgreSQL where every replica can see it.
|
|
190
231
|
|
|
232
|
+
## Serialize Work Across Processes
|
|
233
|
+
|
|
234
|
+
```ts
|
|
235
|
+
import { fileLock } from "@dbx-tools/core";
|
|
236
|
+
|
|
237
|
+
await fileLock.withFileLock(["cache", name], async () => {
|
|
238
|
+
if (!(await exists(name))) await build(name);
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
`withFileLock()` serializes processes on the same machine or shared filesystem.
|
|
243
|
+
Under Bun on Unix it prefers a kernel `flock(2)` lock, which the OS releases if
|
|
244
|
+
the process dies. Plain Node, Windows, and systems without the FFI path use
|
|
245
|
+
atomic lock-directory creation with a heartbeat and stale-lock reclamation.
|
|
246
|
+
Callers can select the lock directory, restrict the backend cascade, observe the
|
|
247
|
+
chosen backend, or set a wait timeout. Lock keys use the same stable structured
|
|
248
|
+
identity as process and Postgres advisory locks.
|
|
249
|
+
|
|
250
|
+
Use `processLock.withProcessLock()` when only threads in one process compete,
|
|
251
|
+
`fileLock.withFileLock()` when local processes compete, and Postgres advisory
|
|
252
|
+
locks when multiple app replicas need one arbiter.
|
|
253
|
+
|
|
191
254
|
## Discover Project Roots
|
|
192
255
|
|
|
193
256
|
```ts
|
|
@@ -210,6 +273,11 @@ basename. `project.stat()` returns `undefined` instead of throwing.
|
|
|
210
273
|
- `project` - root discovery, project naming, git-remote parsing, and safe
|
|
211
274
|
filesystem stat.
|
|
212
275
|
- `brand` - YAML/JSON discovery, parsing, validation, and asset path resolution.
|
|
276
|
+
- `config` - scoped environment, dotenv, and validated Databricks bundle lookup,
|
|
277
|
+
including runtime detection and typed coercion helpers.
|
|
278
|
+
- `file` - best-effort filesystem stat.
|
|
279
|
+
- `fileLock` - cascading cross-process locks using `flock` or portable lock
|
|
280
|
+
directories.
|
|
213
281
|
- `processLock` - keyed mutual exclusion across the main thread and its workers,
|
|
214
282
|
with worker wiring (`processLockWorkerOptions`, `attachProcessLock`,
|
|
215
283
|
`processLockAttached`).
|
package/index.ts
CHANGED
|
@@ -13,8 +13,8 @@ export * as project from "./src/project.ts";
|
|
|
13
13
|
export type { BinContext, BinSelectionContext, BinSelector, BinVersionOutput, BinVersionParser, BinOptions, BinUrl } from "./src/bin.ts";
|
|
14
14
|
export { BrandContextSchema, defaultBrandContext, parseBrandContext, brandContextJsonSchema, brandContextPrompt } from "./src/brand.ts";
|
|
15
15
|
export type { BrandContext, BrandContextInput } from "./src/brand.ts";
|
|
16
|
-
export { MAX_TCP_PORT, ENV_ONLY, bundleValue, bundleResourceSchema, bundleEnvEntrySchema, bundleAppSchema } from "./src/config.ts";
|
|
17
|
-
export type { ConfigFile } from "./src/config.ts";
|
|
16
|
+
export { MAX_TCP_PORT, DATABRICKS_APP_ENV_KEY, CONFIG_DOTENV_KEY, CONFIG_BUNDLE_KEY, ENV_ONLY, bundleValue, bundleResourceSchema, bundleEnvEntrySchema, bundleAppSchema } from "./src/config.ts";
|
|
17
|
+
export type { ConfigKey, ConfigSource, ConfigOptions, ConfigFile } from "./src/config.ts";
|
|
18
18
|
export { COMMAND_NOT_FOUND_EXIT_CODE } from "./src/exec.ts";
|
|
19
19
|
export type { ExecStdio, LineHandler, StdioOption, ExecResult, ChildProcessResult, ExecOptions, SyncExecStdio, SyncExecOptions, SpawnArgs } from "./src/exec.ts";
|
|
20
20
|
export type { FileLockBackend, FileLockAcquisition, FileLockOptions } from "./src/file-lock.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -9,8 +9,8 @@ export * as project from "./src/project.ts";
|
|
|
9
9
|
export type { BinContext, BinSelectionContext, BinSelector, BinVersionOutput, BinVersionParser, BinOptions, BinUrl } from "./src/bin.ts";
|
|
10
10
|
export { BrandContextSchema, defaultBrandContext, parseBrandContext, brandContextJsonSchema, brandContextPrompt } from "./src/brand.ts";
|
|
11
11
|
export type { BrandContext, BrandContextInput } from "./src/brand.ts";
|
|
12
|
-
export { MAX_TCP_PORT, ENV_ONLY, bundleValue, bundleResourceSchema, bundleEnvEntrySchema, bundleAppSchema } from "./src/config.ts";
|
|
13
|
-
export type { ConfigFile } from "./src/config.ts";
|
|
12
|
+
export { MAX_TCP_PORT, DATABRICKS_APP_ENV_KEY, CONFIG_DOTENV_KEY, CONFIG_BUNDLE_KEY, ENV_ONLY, bundleValue, bundleResourceSchema, bundleEnvEntrySchema, bundleAppSchema } from "./src/config.ts";
|
|
13
|
+
export type { ConfigKey, ConfigSource, ConfigOptions, ConfigFile } from "./src/config.ts";
|
|
14
14
|
export { COMMAND_NOT_FOUND_EXIT_CODE } from "./src/exec.ts";
|
|
15
15
|
export type { ExecStdio, LineHandler, StdioOption, ExecResult, ChildProcessResult, ExecOptions, SyncExecStdio, SyncExecOptions, SpawnArgs } from "./src/exec.ts";
|
|
16
16
|
export type { FileLockBackend, FileLockAcquisition, FileLockOptions } from "./src/file-lock.ts";
|
package/lib/index.js
CHANGED
|
@@ -10,6 +10,6 @@ export * as fileLock from "./src/file-lock.js";
|
|
|
10
10
|
export * as processLock from "./src/process-lock.js";
|
|
11
11
|
export * as project from "./src/project.js";
|
|
12
12
|
export { BrandContextSchema, defaultBrandContext, parseBrandContext, brandContextJsonSchema, brandContextPrompt } from "./src/brand.js";
|
|
13
|
-
export { MAX_TCP_PORT, ENV_ONLY, bundleValue, bundleResourceSchema, bundleEnvEntrySchema, bundleAppSchema } from "./src/config.js";
|
|
13
|
+
export { MAX_TCP_PORT, DATABRICKS_APP_ENV_KEY, CONFIG_DOTENV_KEY, CONFIG_BUNDLE_KEY, ENV_ONLY, bundleValue, bundleResourceSchema, bundleEnvEntrySchema, bundleAppSchema } from "./src/config.js";
|
|
14
14
|
export { COMMAND_NOT_FOUND_EXIT_CODE } from "./src/exec.js";
|
|
15
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxPQUFPLEtBQUssR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUNwQyxPQUFPLEtBQUssS0FBSyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLElBQUksTUFBTSxlQUFlLENBQUM7QUFDdEMsT0FBTyxLQUFLLFFBQVEsTUFBTSxvQkFBb0IsQ0FBQztBQUMvQyxPQUFPLEtBQUssV0FBVyxNQUFNLHVCQUF1QixDQUFDO0FBQ3JELE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFFNUMsT0FBTyxFQUFFLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLGlCQUFpQixFQUFFLHNCQUFzQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFeEksT0FBTyxFQUFFLFlBQVksRUFBRSxzQkFBc0IsRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRWpNLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCAqIGFzIGJpbiBmcm9tIFwiLi9zcmMvYmluLnRzXCI7XG5leHBvcnQgKiBhcyBicmFuZCBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCAqIGFzIGNvbmZpZyBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgKiBhcyBleGVjIGZyb20gXCIuL3NyYy9leGVjLnRzXCI7XG5leHBvcnQgKiBhcyBmaWxlIGZyb20gXCIuL3NyYy9maWxlLnRzXCI7XG5leHBvcnQgKiBhcyBmaWxlTG9jayBmcm9tIFwiLi9zcmMvZmlsZS1sb2NrLnRzXCI7XG5leHBvcnQgKiBhcyBwcm9jZXNzTG9jayBmcm9tIFwiLi9zcmMvcHJvY2Vzcy1sb2NrLnRzXCI7XG5leHBvcnQgKiBhcyBwcm9qZWN0IGZyb20gXCIuL3NyYy9wcm9qZWN0LnRzXCI7XG5leHBvcnQgdHlwZSB7IEJpbkNvbnRleHQsIEJpblNlbGVjdGlvbkNvbnRleHQsIEJpblNlbGVjdG9yLCBCaW5WZXJzaW9uT3V0cHV0LCBCaW5WZXJzaW9uUGFyc2VyLCBCaW5PcHRpb25zLCBCaW5VcmwgfSBmcm9tIFwiLi9zcmMvYmluLnRzXCI7XG5leHBvcnQgeyBCcmFuZENvbnRleHRTY2hlbWEsIGRlZmF1bHRCcmFuZENvbnRleHQsIHBhcnNlQnJhbmRDb250ZXh0LCBicmFuZENvbnRleHRKc29uU2NoZW1hLCBicmFuZENvbnRleHRQcm9tcHQgfSBmcm9tIFwiLi9zcmMvYnJhbmQudHNcIjtcbmV4cG9ydCB0eXBlIHsgQnJhbmRDb250ZXh0LCBCcmFuZENvbnRleHRJbnB1dCB9IGZyb20gXCIuL3NyYy9icmFuZC50c1wiO1xuZXhwb3J0IHsgTUFYX1RDUF9QT1JULCBEQVRBQlJJQ0tTX0FQUF9FTlZfS0VZLCBDT05GSUdfRE9URU5WX0tFWSwgQ09ORklHX0JVTkRMRV9LRVksIEVOVl9PTkxZLCBidW5kbGVWYWx1ZSwgYnVuZGxlUmVzb3VyY2VTY2hlbWEsIGJ1bmRsZUVudkVudHJ5U2NoZW1hLCBidW5kbGVBcHBTY2hlbWEgfSBmcm9tIFwiLi9zcmMvY29uZmlnLnRzXCI7XG5leHBvcnQgdHlwZSB7IENvbmZpZ0tleSwgQ29uZmlnU291cmNlLCBDb25maWdPcHRpb25zLCBDb25maWdGaWxlIH0gZnJvbSBcIi4vc3JjL2NvbmZpZy50c1wiO1xuZXhwb3J0IHsgQ09NTUFORF9OT1RfRk9VTkRfRVhJVF9DT0RFIH0gZnJvbSBcIi4vc3JjL2V4ZWMudHNcIjtcbmV4cG9ydCB0eXBlIHsgRXhlY1N0ZGlvLCBMaW5lSGFuZGxlciwgU3RkaW9PcHRpb24sIEV4ZWNSZXN1bHQsIENoaWxkUHJvY2Vzc1Jlc3VsdCwgRXhlY09wdGlvbnMsIFN5bmNFeGVjU3RkaW8sIFN5bmNFeGVjT3B0aW9ucywgU3Bhd25BcmdzIH0gZnJvbSBcIi4vc3JjL2V4ZWMudHNcIjtcbmV4cG9ydCB0eXBlIHsgRmlsZUxvY2tCYWNrZW5kLCBGaWxlTG9ja0FjcXVpc2l0aW9uLCBGaWxlTG9ja09wdGlvbnMgfSBmcm9tIFwiLi9zcmMvZmlsZS1sb2NrLnRzXCI7XG5leHBvcnQgdHlwZSB7IFByb2plY3RDb250ZXh0IH0gZnJvbSBcIi4vc3JjL3Byb2plY3QudHNcIjtcbiJdfQ==
|
package/lib/src/config.d.ts
CHANGED
|
@@ -14,20 +14,44 @@
|
|
|
14
14
|
* the spawn happens once per working directory and a `cwd` change misses
|
|
15
15
|
* rather than returning another project's config.
|
|
16
16
|
*
|
|
17
|
-
* Inside a deployed Databricks App both file sources are skipped
|
|
17
|
+
* Inside a deployed Databricks App both file sources are skipped by default
|
|
18
18
|
* ({@link isDatabricksAppEnv}): the platform has already turned them into real
|
|
19
19
|
* environment variables, there is no bundle to validate, and the `databricks`
|
|
20
|
-
* CLI is not on the image.
|
|
20
|
+
* CLI is not on the image. Boolean environment overrides can force either file
|
|
21
|
+
* source on or off when a tool needs different behavior.
|
|
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.
|
|
21
45
|
*
|
|
22
46
|
* Node-only (`child_process`, `fs`, `process`).
|
|
23
47
|
*
|
|
24
48
|
* @module
|
|
25
49
|
*/
|
|
26
50
|
import { z } from "zod";
|
|
27
|
-
type ConfigKey = string | readonly string[];
|
|
51
|
+
export type ConfigKey = string | readonly string[];
|
|
28
52
|
/** Where a value may come from, consulted in the order given. */
|
|
29
|
-
type ConfigSource = "env" | "dotenv" | "bundle";
|
|
30
|
-
interface ConfigOptions {
|
|
53
|
+
export type ConfigSource = "env" | "dotenv" | "bundle";
|
|
54
|
+
export interface ConfigOptions {
|
|
31
55
|
/**
|
|
32
56
|
* Outermost namespaces tried before each key. Defaults to `DBX_TOOLS`.
|
|
33
57
|
*/
|
|
@@ -46,6 +70,12 @@ export interface ConfigFile {
|
|
|
46
70
|
}
|
|
47
71
|
/** Highest valid TCP port number. */
|
|
48
72
|
export declare const MAX_TCP_PORT = 65535;
|
|
73
|
+
/** Boolean environment override for {@link isDatabricksAppEnv}. */
|
|
74
|
+
export declare const DATABRICKS_APP_ENV_KEY = "DBX_TOOLS_DATABRICKS_APP_ENV";
|
|
75
|
+
/** Boolean environment override for project `.env` reads. */
|
|
76
|
+
export declare const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
|
|
77
|
+
/** Boolean environment override for Databricks bundle reads. */
|
|
78
|
+
export declare const CONFIG_BUNDLE_KEY = "DBX_TOOLS_CONFIG_BUNDLE";
|
|
49
79
|
/** Exact process-environment lookup for callers that do not read local config files. */
|
|
50
80
|
export declare const ENV_ONLY: {
|
|
51
81
|
scope: readonly [];
|
|
@@ -83,6 +113,11 @@ export declare const bundleAppSchema: z.ZodObject<{
|
|
|
83
113
|
}, z.core.$strip>;
|
|
84
114
|
/**
|
|
85
115
|
* Detect a Databricks App runtime from its required name, host, and port.
|
|
116
|
+
*
|
|
117
|
+
* `DBX_TOOLS_DATABRICKS_APP_ENV` takes precedence when it contains a recognized
|
|
118
|
+
* boolean value. This lets local tools emulate the deployed runtime (`true`) or
|
|
119
|
+
* lets unusual deployed processes retain local config lookup (`false`). An
|
|
120
|
+
* absent or unrecognized override falls back to structural detection.
|
|
86
121
|
*/
|
|
87
122
|
export declare function isDatabricksAppEnv(source?: Record<string, string | undefined>): boolean;
|
|
88
123
|
/**
|
|
@@ -135,13 +170,21 @@ export declare function list(configured: string | readonly string[] | undefined
|
|
|
135
170
|
/**
|
|
136
171
|
* The Databricks bundle output for `cwd` - `databricks bundle validate --output
|
|
137
172
|
* json` run from the directory holding `databricks.yml`, with the config file's
|
|
138
|
-
* path. A non-zero validation may still return partial JSON with usable
|
|
139
|
-
*
|
|
140
|
-
*
|
|
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.
|
|
141
184
|
*
|
|
142
|
-
* Cached per working
|
|
143
|
-
* {@link context.cached}, so
|
|
144
|
-
*
|
|
185
|
+
* Cached once per resolved working-directory context and
|
|
186
|
+
* `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
|
|
187
|
+
* lookups do not rerun validation and changing either cannot return another
|
|
188
|
+
* context's bundle.
|
|
145
189
|
*/
|
|
146
190
|
export declare function bundleFile(cwd?: string | null): ConfigFile | undefined;
|
|
147
|
-
export {};
|
package/lib/src/config.js
CHANGED
|
@@ -14,20 +14,53 @@
|
|
|
14
14
|
* the spawn happens once per working directory and a `cwd` change misses
|
|
15
15
|
* rather than returning another project's config.
|
|
16
16
|
*
|
|
17
|
-
* Inside a deployed Databricks App both file sources are skipped
|
|
17
|
+
* Inside a deployed Databricks App both file sources are skipped by default
|
|
18
18
|
* ({@link isDatabricksAppEnv}): the platform has already turned them into real
|
|
19
19
|
* environment variables, there is no bundle to validate, and the `databricks`
|
|
20
|
-
* CLI is not on the image.
|
|
20
|
+
* CLI is not on the image. Boolean environment overrides can force either file
|
|
21
|
+
* source on or off when a tool needs different behavior.
|
|
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.
|
|
21
45
|
*
|
|
22
46
|
* Node-only (`child_process`, `fs`, `process`).
|
|
23
47
|
*
|
|
24
48
|
* @module
|
|
25
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
|
+
};
|
|
26
58
|
import { spawnSync } from "node:child_process";
|
|
27
59
|
import { readFileSync } from "node:fs";
|
|
60
|
+
import { createRequire } from "node:module";
|
|
28
61
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
29
62
|
import { parseEnv } from "node:util";
|
|
30
|
-
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";
|
|
31
64
|
import { z } from "zod";
|
|
32
65
|
import { statSync } from "./file.js";
|
|
33
66
|
import { root as resolveProjectRoot } from "./project.js";
|
|
@@ -42,6 +75,26 @@ const NODE_ENV_ALTERNATIVES = {
|
|
|
42
75
|
};
|
|
43
76
|
/** Highest valid TCP port number. */
|
|
44
77
|
export const MAX_TCP_PORT = 65_535;
|
|
78
|
+
/** Boolean environment override for {@link isDatabricksAppEnv}. */
|
|
79
|
+
export const DATABRICKS_APP_ENV_KEY = "DBX_TOOLS_DATABRICKS_APP_ENV";
|
|
80
|
+
/** Boolean environment override for project `.env` reads. */
|
|
81
|
+
export const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
|
|
82
|
+
/** Boolean environment override for Databricks bundle reads. */
|
|
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();
|
|
45
98
|
/** Exact process-environment lookup for callers that do not read local config files. */
|
|
46
99
|
export const ENV_ONLY = { scope: [], sources: "env" };
|
|
47
100
|
export const bundleValue = z
|
|
@@ -64,10 +117,6 @@ export const bundleEnvEntrySchema = z.object({
|
|
|
64
117
|
value: z.string().optional(),
|
|
65
118
|
value_from: bundleValue.optional(),
|
|
66
119
|
});
|
|
67
|
-
const bundleVariableSchema = z.object({
|
|
68
|
-
default: z.string().optional(),
|
|
69
|
-
value: z.string().optional(),
|
|
70
|
-
});
|
|
71
120
|
export const bundleAppSchema = z.object({
|
|
72
121
|
name: bundleValue.optional(),
|
|
73
122
|
source_code_path: z.string().optional(),
|
|
@@ -77,13 +126,18 @@ export const bundleAppSchema = z.object({
|
|
|
77
126
|
const bundleAppsSchema = z.object({
|
|
78
127
|
resources: z.object({ apps: z.record(z.string(), bundleAppSchema).optional() }).optional(),
|
|
79
128
|
});
|
|
80
|
-
const bundleVariablesSchema = z.object({
|
|
81
|
-
variables: z.record(z.string(), bundleVariableSchema).optional(),
|
|
82
|
-
});
|
|
83
129
|
/**
|
|
84
130
|
* Detect a Databricks App runtime from its required name, host, and port.
|
|
131
|
+
*
|
|
132
|
+
* `DBX_TOOLS_DATABRICKS_APP_ENV` takes precedence when it contains a recognized
|
|
133
|
+
* boolean value. This lets local tools emulate the deployed runtime (`true`) or
|
|
134
|
+
* lets unusual deployed processes retain local config lookup (`false`). An
|
|
135
|
+
* absent or unrecognized override falls back to structural detection.
|
|
85
136
|
*/
|
|
86
137
|
export function isDatabricksAppEnv(source = process.env) {
|
|
138
|
+
const override = object.toBoolean(source[DATABRICKS_APP_ENV_KEY]);
|
|
139
|
+
if (override !== undefined)
|
|
140
|
+
return override;
|
|
87
141
|
const appName = source.DATABRICKS_APP_NAME?.trim();
|
|
88
142
|
const host = source.DATABRICKS_HOST?.trim();
|
|
89
143
|
const port = source.DATABRICKS_APP_PORT?.trim();
|
|
@@ -239,17 +293,52 @@ function toPositiveNumber(value) {
|
|
|
239
293
|
/**
|
|
240
294
|
* The Databricks bundle output for `cwd` - `databricks bundle validate --output
|
|
241
295
|
* json` run from the directory holding `databricks.yml`, with the config file's
|
|
242
|
-
* path. A non-zero validation may still return partial JSON with usable
|
|
243
|
-
*
|
|
244
|
-
*
|
|
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.
|
|
245
307
|
*
|
|
246
|
-
* Cached per working
|
|
247
|
-
* {@link context.cached}, so
|
|
248
|
-
*
|
|
308
|
+
* Cached once per resolved working-directory context and
|
|
309
|
+
* `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
|
|
310
|
+
* lookups do not rerun validation and changing either cannot return another
|
|
311
|
+
* context's bundle.
|
|
249
312
|
*/
|
|
250
313
|
export function bundleFile(cwd) {
|
|
314
|
+
const production = process.env.NODE_ENV?.trim().toLowerCase() === "production";
|
|
315
|
+
const override = object.toBoolean(process.env[CONFIG_BUNDLE_KEY]);
|
|
316
|
+
if (override === false)
|
|
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
|
+
}
|
|
251
327
|
const profile = stringModule.trimToNull(process.env.DATABRICKS_CONFIG_PROFILE);
|
|
252
|
-
|
|
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;
|
|
253
342
|
}
|
|
254
343
|
/**
|
|
255
344
|
* The single App's literal `config.env` entries, flattened to `name -> value`.
|
|
@@ -260,8 +349,24 @@ export function bundleFile(cwd) {
|
|
|
260
349
|
* {@link bundleResourceSchema}. An `apps` block with more than one app is
|
|
261
350
|
* ambiguous (nothing here says which app this process is), so it yields nothing
|
|
262
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.
|
|
263
357
|
*/
|
|
264
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) {
|
|
265
370
|
const parsed = bundleAppsSchema.safeParse(input);
|
|
266
371
|
if (!parsed.success)
|
|
267
372
|
return {};
|
|
@@ -283,35 +388,89 @@ function bundleApp(input) {
|
|
|
283
388
|
return result;
|
|
284
389
|
}
|
|
285
390
|
/**
|
|
286
|
-
*
|
|
391
|
+
* Whether `@databricks/appkit` can be RESOLVED from this process, cached for its
|
|
392
|
+
* lifetime.
|
|
287
393
|
*
|
|
288
|
-
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
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.
|
|
292
399
|
*/
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
const value = resolvedString(variable.value) ?? resolvedString(variable.default);
|
|
301
|
-
if (key && value !== null)
|
|
302
|
-
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;
|
|
303
407
|
}
|
|
304
|
-
|
|
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);
|
|
305
456
|
}
|
|
306
457
|
/** A non-empty bundle value with every `${...}` interpolation resolved. */
|
|
307
458
|
function resolvedString(value) {
|
|
308
459
|
const parsed = bundleValue.safeParse(value);
|
|
309
460
|
return parsed.success ? parsed.data : null;
|
|
310
461
|
}
|
|
311
|
-
/** Parsed `.env` for `cwd`, or `{}`.
|
|
462
|
+
/** Parsed `.env` for `cwd`, or `{}`. Read once per resolved context. */
|
|
312
463
|
function dotenv(cwd) {
|
|
464
|
+
if (!fileSourceEnabled(CONFIG_DOTENV_KEY))
|
|
465
|
+
return {};
|
|
313
466
|
const environments = nodeEnvNames(process.env.NODE_ENV);
|
|
314
|
-
return
|
|
467
|
+
return cachedConfig(["dotenv", ...environments], cwd, (resolved) => loadDotenv(resolved, environments));
|
|
468
|
+
}
|
|
469
|
+
/** Cache every target directory separately within the active process context. */
|
|
470
|
+
function cachedConfig(name, cwd, loader) {
|
|
471
|
+
const active = context.getContext() ?? "";
|
|
472
|
+
const resolved = resolve(cwd ?? ".");
|
|
473
|
+
return context.cached(["config", active, resolved, ...name], () => loader(resolved));
|
|
315
474
|
}
|
|
316
475
|
/**
|
|
317
476
|
* Maps for one source in precedence order. Bundle App config and root variables
|
|
@@ -330,10 +489,8 @@ function read(source, cwd) {
|
|
|
330
489
|
break;
|
|
331
490
|
case "bundle": {
|
|
332
491
|
const bundle = bundleFile(cwd);
|
|
333
|
-
if (bundle)
|
|
492
|
+
if (bundle)
|
|
334
493
|
yield bundleApp(bundle.data);
|
|
335
|
-
yield bundleVariables(bundle.data);
|
|
336
|
-
}
|
|
337
494
|
break;
|
|
338
495
|
}
|
|
339
496
|
}
|
|
@@ -345,8 +502,6 @@ function read(source, cwd) {
|
|
|
345
502
|
* discovered project roots so a package-local file wins over the workspace's.
|
|
346
503
|
*/
|
|
347
504
|
function findConfigFile(cwd, names) {
|
|
348
|
-
if (isDatabricksAppEnv())
|
|
349
|
-
return undefined;
|
|
350
505
|
const start = resolve(cwd);
|
|
351
506
|
const root = resolveProjectRoot(start);
|
|
352
507
|
const pathFromRoot = root ? relative(root, start) : undefined;
|
|
@@ -368,6 +523,10 @@ function findConfigFile(cwd, names) {
|
|
|
368
523
|
}
|
|
369
524
|
return undefined;
|
|
370
525
|
}
|
|
526
|
+
/** A recognized source override, else the caller's automatic default. */
|
|
527
|
+
function fileSourceEnabled(key, fallback = !isDatabricksAppEnv()) {
|
|
528
|
+
return object.toBoolean(process.env[key]) ?? fallback;
|
|
529
|
+
}
|
|
371
530
|
function loadDotenv(cwd, environments) {
|
|
372
531
|
const names = [...environments.map((name) => `${DOTENV_FILE_NAME}.${name}`), DOTENV_FILE_NAME];
|
|
373
532
|
const path = findConfigFile(cwd, names);
|
|
@@ -413,4 +572,4 @@ function loadBundleFile(cwd, profile) {
|
|
|
413
572
|
}
|
|
414
573
|
return { path, data };
|
|
415
574
|
}
|
|
416
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2NvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBd0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDdkMsT0FBTyxFQUFFLE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDeEUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNyQyxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sSUFBSSxZQUFZLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM1RixPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3hCLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDckMsT0FBTyxFQUFFLElBQUksSUFBSSxrQkFBa0IsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUUxRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0FBaUNwQyxNQUFNLGFBQWEsR0FBRyxXQUFXLENBQUM7QUFDbEMsTUFBTSxlQUFlLEdBQTRCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQztBQUM3RSxNQUFNLGlCQUFpQixHQUFHLENBQUMsZ0JBQWdCLEVBQUUsaUJBQWlCLENBQVUsQ0FBQztBQUN6RSxNQUFNLGdCQUFnQixHQUFHLE1BQU0sQ0FBQztBQUNoQyxNQUFNLHFCQUFxQixHQUFHO0lBQzVCLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUNwQixXQUFXLEVBQUUsQ0FBQyxLQUFLLENBQUM7Q0FD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UyxDQUFDO0lBQ25CLENBQUM7SUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3RDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNWLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0NBQXdDLEVBQUUsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZGLE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7SUFDRCxJQUFJLE1BQU0sQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDeEIsTUFBTSxDQUFDLEtBQUssQ0FBQyw2QkFBNkIsRUFBRSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0lBQ3RGLENBQUM7SUFDRCxPQUFPLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDO0FBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExheWVyZWQgY29uZmlndXJhdGlvbiBsb29rdXA6IGVudmlyb25tZW50LCBgLmVudmAsIERhdGFicmlja3MgYnVuZGxlLlxuICpcbiAqIEV2ZXJ5IHBhY2thZ2UgcmVzb2x2ZXMgc2V0dGluZ3MgdGhlIHNhbWUgd2F5OiB0YWtlIHRoZSBjYWxsZXIncyB2YWx1ZSwgZWxzZVxuICogYW4gZW52aXJvbm1lbnQgdmFyaWFibGUsIGVsc2UgYSBkZWZhdWx0LiBMb2NhbCBkZXZlbG9wbWVudCBhZGRzIHR3byBmYWxsYmFja1xuICogbG9jYXRpb25zOiBgLmVudmAgZmlsZXMgYW5kIGByZXNvdXJjZXMuYXBwcy48YXBwPi5jb25maWcuZW52YCBvciByb290XG4gKiBgdmFyaWFibGVzYCBpbiBgZGF0YWJyaWNrcy55bWxgLlxuICpcbiAqIFR3byB0aGluZ3MgbWFrZSBpdCBjaGVhcCB0byBjYWxsIGZyb20gYSBob3QgcGF0aDpcbiAqXG4gKiAgIC0ge0BsaW5rIHZhbHVlc30gaXMgTEFaWSAoYW4gYG9iamVjdC5TZXF1ZW5jZWApLCBzbyBgZGF0YWJyaWNrcyBidW5kbGVcbiAqICAgICB2YWxpZGF0ZWAgaXMgb25seSBzcGF3bmVkIHdoZW4gdGhlIGVudmlyb25tZW50IGFuZCBgLmVudmAgYm90aCBtaXNzZWQuXG4gKiAgIC0gdGhlIHBhcnNlZCBgLmVudmAgYW5kIGJ1bmRsZSBhcmUgY2FjaGVkIHRocm91Z2gge0BsaW5rIGNvbnRleHQuY2FjaGVkfSwgc29cbiAqICAgICB0aGUgc3Bhd24gaGFwcGVucyBvbmNlIHBlciB3b3JraW5nIGRpcmVjdG9yeSBhbmQgYSBgY3dkYCBjaGFuZ2UgbWlzc2VzXG4gKiAgICAgcmF0aGVyIHRoYW4gcmV0dXJuaW5nIGFub3RoZXIgcHJvamVjdCdzIGNvbmZpZy5cbiAqXG4gKiBJbnNpZGUgYSBkZXBsb3llZCBEYXRhYnJpY2tzIEFwcCBib3RoIGZpbGUgc291cmNlcyBhcmUgc2tpcHBlZCBvdXRyaWdodFxuICogKHtAbGluayBpc0RhdGFicmlja3NBcHBFbnZ9KTogdGhlIHBsYXRmb3JtIGhhcyBhbHJlYWR5IHR1cm5lZCB0aGVtIGludG8gcmVhbFxuICogZW52aXJvbm1lbnQgdmFyaWFibGVzLCB0aGVyZSBpcyBubyBidW5kbGUgdG8gdmFsaWRhdGUsIGFuZCB0aGUgYGRhdGFicmlja3NgXG4gKiBDTEkgaXMgbm90IG9uIHRoZSBpbWFnZS5cbiAqXG4gKiBOb2RlLW9ubHkgKGBjaGlsZF9wcm9jZXNzYCwgYGZzYCwgYHByb2Nlc3NgKS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgc3Bhd25TeW5jIH0gZnJvbSBcIm5vZGU6Y2hpbGRfcHJvY2Vzc1wiO1xuaW1wb3J0IHsgcmVhZEZpbGVTeW5jIH0gZnJvbSBcIm5vZGU6ZnNcIjtcbmltcG9ydCB7IGRpcm5hbWUsIGlzQWJzb2x1dGUsIHJlbGF0aXZlLCByZXNvbHZlLCBzZXAgfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQgeyBwYXJzZUVudiB9IGZyb20gXCJub2RlOnV0aWxcIjtcbmltcG9ydCB7IGNvbnRleHQsIGpzb24sIGxvZywgb2JqZWN0LCBzdHJpbmcgYXMgc3RyaW5nTW9kdWxlIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBzdGF0U3luYyB9IGZyb20gXCIuL2ZpbGUudHNcIjtcbmltcG9ydCB7IHJvb3QgYXMgcmVzb2x2ZVByb2plY3RSb290IH0gZnJvbSBcIi4vcHJvamVjdC50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiY29uZmlnXCIpO1xuXG50eXBlIENvbmZpZ0tleSA9IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuXG4vKiogV2hlcmUgYSB2YWx1ZSBtYXkgY29tZSBmcm9tLCBjb25zdWx0ZWQgaW4gdGhlIG9yZGVyIGdpdmVuLiAqL1xudHlwZSBDb25maWdTb3VyY2UgPSBcImVudlwiIHwgXCJkb3RlbnZcIiB8IFwiYnVuZGxlXCI7XG5cbmludGVyZmFjZSBDb25maWdPcHRpb25zIHtcbiAgLyoqXG4gICAqIE91dGVybW9zdCBuYW1lc3BhY2VzIHRyaWVkIGJlZm9yZSBlYWNoIGtleS4gRGVmYXVsdHMgdG8gYERCWF9UT09MU2AuXG4gICAqL1xuICBzY29wZT86IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdO1xuICAvKiogQ2FwYWJpbGl0eSBuYW1lc3BhY2VzIGluc2VydGVkIGFmdGVyIHRoZSBzY29wZSBhbmQgYmVmb3JlIGVhY2gga2V5LiAqL1xuICBwcmVmaXg/OiBzdHJpbmcgfCByZWFkb25seSBzdHJpbmdbXTtcbiAgLyoqIERpcmVjdG9yeSB0byByZXNvbHZlIGAuZW52YCBhbmQgdGhlIGJ1bmRsZSBmcm9tLiBEZWZhdWx0OiBgcHJvY2Vzcy5jd2QoKWAuICovXG4gIGN3ZD86IHN0cmluZztcbiAgLyoqIFNvdXJjZXMgaW4gcHJlY2VkZW5jZSBvcmRlci4gRGVmYXVsdDogYGVudmAsIGBkb3RlbnZgLCBgYnVuZGxlYC4gKi9cbiAgc291cmNlcz86IENvbmZpZ1NvdXJjZSB8IHJlYWRvbmx5IENvbmZpZ1NvdXJjZVtdO1xufVxuXG4vKiogT25lIHJlc29sdmVkIHZhbHVlLCB0YWdnZWQgd2l0aCB0aGUga2V5IGFuZCBzb3VyY2UgaXQgY2FtZSBmcm9tLiAqL1xuaW50ZXJmYWNlIENvbmZpZ1ZhbHVlIHtcbiAga2V5OiBzdHJpbmc7XG4gIHNvdXJjZTogQ29uZmlnU291cmNlO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG4vKiogQSBjb25maWcgZmlsZSBmb3VuZCBvbiBkaXNrLCB3aXRoIGl0cyBwYXJzZWQgY29udGVudHMuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZ0ZpbGUge1xuICBwYXRoOiBzdHJpbmc7XG4gIGRhdGE6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xufVxuXG5jb25zdCBERUZBVUxUX1NDT1BFID0gXCJEQlhfVE9PTFNcIjtcbmNvbnN0IERFRkFVTFRfU09VUkNFUzogcmVhZG9ubHkgQ29uZmlnU291cmNlW10gPSBbXCJlbnZcIiwgXCJkb3RlbnZcIiwgXCJidW5kbGVcIl07XG5jb25zdCBCVU5ETEVfRklMRV9OQU1FUyA9IFtcImRhdGFicmlja3MueW1sXCIsIFwiZGF0YWJyaWNrcy55YW1sXCJdIGFzIGNvbnN0O1xuY29uc3QgRE9URU5WX0ZJTEVfTkFNRSA9IFwiLmVudlwiO1xuY29uc3QgTk9ERV9FTlZfQUxURVJOQVRJVkVTID0ge1xuICBwcm9kdWN0aW9uOiBbXCJwcm9kXCJdLFxuICBkZXZlbG9wbWVudDogW1wiZGV2XCJdLFxufSBhcyBjb25zdCBzYXRpc2ZpZXMgUmVjb3JkPHN0cmluZywgcmVhZG9ubHkgc3RyaW5nW10+O1xuXG4vKiogSGlnaGVzdCB2YWxpZCBUQ1AgcG9ydCBudW1iZXIuICovXG5leHBvcnQgY29uc3QgTUFYX1RDUF9QT1JUID0gNjVfNTM1O1xuXG4vKiogRXhhY3QgcHJvY2Vzcy1lbnZpcm9ubWVudCBsb29rdXAgZm9yIGNhbGxlcnMgdGhhdCBkbyBub3QgcmVhZCBsb2NhbCBjb25maWcgZmlsZXMuICovXG5leHBvcnQgY29uc3QgRU5WX09OTFkgPSB7IHNjb3BlOiBbXSBhcyBjb25zdCwgc291cmNlczogXCJlbnZcIiBhcyBjb25zdCB9O1xuXG5leHBvcnQgY29uc3QgYnVuZGxlVmFsdWUgPSB6XG4gIC5zdHJpbmcoKVxuICAudHJhbnNmb3JtKCh2YWx1ZTogc3RyaW5nKSA9PiB2YWx1ZS50cmltKCkpXG4gIC5yZWZpbmUoKHZhbHVlOiBzdHJpbmcpID0+IHZhbHVlLmxlbmd0aCA+IDApXG4gIC5yZWZpbmUoKHZhbHVlOiBzdHJpbmcpID0+ICEvXFwkXFx7W159XStcXH0vLnRlc3QodmFsdWUpLCB7XG4gICAgbWVzc2FnZTogXCJJbnRlcnBvbGF0ZWQgdmFsdWVzIGFyZSBub3QgYWxsb3dlZFwiLFxuICB9KTtcblxuLyoqXG4gKiBUaGUgR0VORVJJQyBzaGFwZSBvZiBhIGJ1bmRsZSByZXNvdXJjZTogYSBuYW1lLCBhbmQgd2hhdGV2ZXIgZWxzZSB0aGUgcmVzb3VyY2VcbiAqIHR5cGUgY2Fycmllcy4gRGVsaWJlcmF0ZWx5IHVub3BpbmlvbmF0ZWQgYW5kIGBwYXNzdGhyb3VnaCgpYCAtIHRoZSBjb25jcmV0ZVxuICogcmVzb3VyY2Uga2luZHMgKGBzcWxfd2FyZWhvdXNlYCwgYGdlbmllX3NwYWNlYCwgYHBvc3RncmVzYCwgLi4uKSBhcmVcbiAqIERhdGFicmlja3MtQXBwIGNvbmNlcHRzIHRoYXQgYmVsb25nIHRvIHRoZSBwYWNrYWdlIHRoYXQgcmVzb2x2ZXMgdGhlbSwgc29cbiAqIG5vZGUtYXBwa2l0IGAuZXh0ZW5kKClgcyB0aGlzIHJhdGhlciB0aGFuIHRoaXMgbW9kdWxlIGtub3dpbmcgYWJvdXQgdGhlbS5cbiAqL1xuZXhwb3J0IGNvbnN0IGJ1bmRsZVJlc291cmNlU2NoZW1hID0gei5vYmplY3QoeyBuYW1lOiBidW5kbGVWYWx1ZS5vcHRpb25hbCgpIH0pLnBhc3N0aHJvdWdoKCk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVFbnZFbnRyeVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgbmFtZTogYnVuZGxlVmFsdWUub3B0aW9uYWwoKSxcbiAgdmFsdWU6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgdmFsdWVfZnJvbTogYnVuZGxlVmFsdWUub3B0aW9uYWwoKSxcbn0pO1xuXG5jb25zdCBidW5kbGVWYXJpYWJsZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgZGVmYXVsdDogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxuICB2YWx1ZTogei5zdHJpbmcoKS5vcHRpb25hbCgpLFxufSk7XG5cbmV4cG9ydCBjb25zdCBidW5kbGVBcHBTY2hlbWEgPSB6Lm9iamVjdCh7XG4gIG5hbWU6IGJ1bmRsZVZhbHVlLm9wdGlvbmFsKCksXG4gIHNvdXJjZV9jb2RlX3BhdGg6IHouc3RyaW5nKCkub3B0aW9uYWwoKSxcbiAgY29uZmlnOiB6Lm9iamVjdCh7IGVudjogei5hcnJheShidW5kbGVFbnZFbnRyeVNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxuICByZXNvdXJjZXM6IHouYXJyYXkoYnVuZGxlUmVzb3VyY2VTY2hlbWEpLm9wdGlvbmFsKCksXG59KTtcblxuY29uc3QgYnVuZGxlQXBwc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgcmVzb3VyY2VzOiB6Lm9iamVjdCh7IGFwcHM6IHoucmVjb3JkKHouc3RyaW5nKCksIGJ1bmRsZUFwcFNjaGVtYSkub3B0aW9uYWwoKSB9KS5vcHRpb25hbCgpLFxufSk7XG5cbmNvbnN0IGJ1bmRsZVZhcmlhYmxlc1NjaGVtYSA9IHoub2JqZWN0KHtcbiAgdmFyaWFibGVzOiB6LnJlY29yZCh6LnN0cmluZygpLCBidW5kbGVWYXJpYWJsZVNjaGVtYSkub3B0aW9uYWwoKSxcbn0pO1xuXG4vKipcbiAqIERldGVjdCBhIERhdGFicmlja3MgQXBwIHJ1bnRpbWUgZnJvbSBpdHMgcmVxdWlyZWQgbmFtZSwgaG9zdCwgYW5kIHBvcnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0RhdGFicmlja3NBcHBFbnYoXG4gIHNvdXJjZTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiA9IHByb2Nlc3MuZW52LFxuKTogYm9vbGVhbiB7XG4gIGNvbnN0IGFwcE5hbWUgPSBzb3VyY2UuREFUQUJSSUNLU19BUFBfTkFNRT8udHJpbSgpO1xuICBjb25zdCBob3N0ID0gc291cmNlLkRBVEFCUklDS1NfSE9TVD8udHJpbSgpO1xuICBjb25zdCBwb3J0ID0gc291cmNlLkRBVEFCUklDS1NfQVBQX1BPUlQ/LnRyaW0oKTtcbiAgaWYgKCFhcHBOYW1lIHx8ICFob3N0IHx8ICFwb3J0KSByZXR1cm4gZmFsc2U7XG4gIHRyeSB7XG4gICAgaWYgKCFbXCJodHRwOlwiLCBcImh0dHBzOlwiXS5pbmNsdWRlcyhuZXcgVVJMKGhvc3QpLnByb3RvY29sKSkgcmV0dXJuIGZhbHNlO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgcG9ydE51bWJlciA9IG9iamVjdC50b051bWJlcihwb3J0KTtcbiAgcmV0dXJuIChcbiAgICBwb3J0TnVtYmVyICE9PSB1bmRlZmluZWQgJiZcbiAgICBOdW1iZXIuaXNJbnRlZ2VyKHBvcnROdW1iZXIpICYmXG4gICAgcG9ydE51bWJlciA+PSAxICYmXG4gICAgcG9ydE51bWJlciA8PSBNQVhfVENQX1BPUlRcbiAgKTtcbn1cblxuLyoqIENhbmRpZGF0ZSBuYW1lcyBpbiBzY29wZSwgcHJlZml4LCBhbmQgaW5wdXQgcHJlY2VkZW5jZSBvcmRlci4gKi9cbmZ1bmN0aW9uIGtleXMoaW5wdXQ6IENvbmZpZ0tleSwgb3B0aW9uczogUGljazxDb25maWdPcHRpb25zLCBcInNjb3BlXCIgfCBcInByZWZpeFwiPiA9IHt9KTogc3RyaW5nW10ge1xuICBjb25zdCBzY29wZXMgPSBvYmplY3Quc2VxdWVuY2Uob3B0aW9ucy5zY29wZSA/PyBERUZBVUxUX1NDT1BFKS50b0FycmF5KCk7XG4gIGNvbnN0IHByZWZpeGVzID0gb3B0aW9ucy5wcmVmaXggPT09IHVuZGVmaW5lZCA/IFtdIDogb2JqZWN0LnNlcXVlbmNlKG9wdGlvbnMucHJlZml4KS50b0FycmF5KCk7XG4gIHJldHVybiBbXG4gICAgLi4ub2JqZWN0XG4gICAgICAuc2VxdWVuY2UoaW5wdXQpXG4gICAgICAuZmxhdE1hcCgoa2V5KSA9PiB7XG4gICAgICAgIGNvbnN0IHByZWZpeGVkID0gcHJlZml4ZXMubGVuZ3RoID4gMCA/IHByZWZpeGVzLm1hcCgocHJlZml4KSA9PiBqb2luKHByZWZpeCwga2V5KSkgOiBba2V5XTtcbiAgICAgICAgcmV0dXJuIFtcbiAgICAgICAgICAuLi5zY29wZXMuZmxhdE1hcCgoc2NvcGUpID0+IHByZWZpeGVkLm1hcCgoa2V5KSA9PiBqb2luKHNjb3BlLCBrZXkpKSksXG4gICAgICAgICAgLi4ucHJlZml4ZWQsXG4gICAgICAgICAga2V5LFxuICAgICAgICBdO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKGtleSkgPT4ga2V5Lmxlbmd0aCA+IDApXG4gICAgICAuZGlzdGluY3QoKSxcbiAgXTtcbn1cblxuLyoqXG4gKiBFdmVyeSB2YWx1ZSB0aGF0IHJlc29sdmVzIGZvciBgaW5wdXRgLCBpbiBzb3VyY2UtdGhlbi1rZXkgcHJlY2VkZW5jZSBvcmRlcixcbiAqIGFzIGEgTEFaWSBzZXF1ZW5jZTogbm90aGluZyBwYXN0IHRoZSBmaXJzdCBjb25zdW1lZCBlbGVtZW50IGlzIHJlYWQsIHNvXG4gKiBgdmFsdWVzKGtleSkuZmlyc3QoKWAgbmV2ZXIgc3Bhd25zIHRoZSBEYXRhYnJpY2tzIENMSSB3aGVuIHRoZSBlbnZpcm9ubWVudFxuICogYWxyZWFkeSBhbnN3ZXJlZC5cbiAqXG4gKi9cbmZ1bmN0aW9uIHZhbHVlcyhpbnB1dDogQ29uZmlnS2V5LCBvcHRpb25zOiBDb25maWdPcHRpb25zID0ge30pOiBvYmplY3QuU2VxdWVuY2U8Q29uZmlnVmFsdWU+IHtcbiAgY29uc3QgY2FuZGlkYXRlcyA9IGtleXMoaW5wdXQsIG9wdGlvbnMpO1xuICBjb25zdCBzb3VyY2VzID0gb2JqZWN0LnNlcXVlbmNlPENvbmZpZ1NvdXJjZT4ob3B0aW9ucy5zb3VyY2VzID8/IERFRkFVTFRfU09VUkNFUyk7XG4gIHJldHVybiBvYmplY3Quc2VxdWVuY2Uoe1xuICAgICpbU3ltYm9sLml0ZXJhdG9yXSgpOiBHZW5lcmF0b3I8Q29uZmlnVmFsdWU+IHtcbiAgICAgIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCBtYXAgb2YgcmVhZChzb3VyY2UsIG9wdGlvbnMuY3dkKSkge1xuICAgICAgICAgIGZvciAoY29uc3Qga2V5IG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgICAgIGNvbnN0IHZhbHVlID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwobWFwW2tleV0pO1xuICAgICAgICAgICAgaWYgKHZhbHVlICE9PSBudWxsKSB5aWVsZCB7IGtleSwgc291cmNlLCB2YWx1ZSB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIFRoZSBmaXJzdCB2YWx1ZSB0aGF0IHJlc29sdmVzIGZvciBgaW5wdXRgLCBvciBgdW5kZWZpbmVkYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgZG9tYWluID0gY29uZmlnLnRleHQoW1wiVFVOTkVMX1BVQkxJQ19ET01BSU5cIiwgXCJQVUJMSUNfRE9NQUlOXCJdKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRleHQoaW5wdXQ6IENvbmZpZ0tleSwgb3B0aW9uczogQ29uZmlnT3B0aW9ucyA9IHt9KTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlcyhpbnB1dCwgb3B0aW9ucykuYXQoMCk/LnZhbHVlO1xufVxuXG4vKipcbiAqIFRoZSBQUklNQVJZIChmdWxseS1zY29wZWQpIG5hbWUgZm9yIGBpbnB1dGAgLSB3aGF0IHRvIHByaW50IGluIGEgbG9nIGxpbmUgb3IgYW5cbiAqIGVycm9yLCBzbyB0aGUgbWVzc2FnZSBuYW1lcyB0aGUgdmFyaWFibGUgYSByZWFkZXIgc2hvdWxkIHNldC4gRG8gbm90IGluZGV4XG4gKiBga2V5cyguLi4pWzBdYCBmb3IgdGhpcyBpZiBgaW5wdXRgIG1heSBiZSBhIGJhcmUgc3RyaW5nLlxuICpcbiAqIEBleGFtcGxlXG4gKiBsb2dnZXIud2FybihgJHtjb25maWcubmFtZShKV1RfU0VDUkVUX0VOVil9IGlzIG5vdCBzZXRgKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hbWUoXG4gIGlucHV0OiBDb25maWdLZXksXG4gIG9wdGlvbnM6IFBpY2s8Q29uZmlnT3B0aW9ucywgXCJzY29wZVwiIHwgXCJwcmVmaXhcIj4gPSB7fSxcbik6IHN0cmluZyB7XG4gIHJldHVybiBrZXlzKGlucHV0LCBvcHRpb25zKVswXSA/PyBcIlwiO1xufVxuXG4vKipcbiAqIFNhZmUgYC5lbnYuPG5hbWU+YCBzdWZmaXhlcyBmb3IgYSBOb2RlIGVudmlyb25tZW50LCBleGFjdCBzcGVsbGluZyBmaXJzdC5cbiAqIEtub3duIGxvbmcgYW5kIHNob3J0IG5hbWVzIGFyZSBpbnRlcmNoYW5nZWFibGU7IHVua25vd24gbmFtZXMgcGFzcyB0aHJvdWdoLlxuICovXG5mdW5jdGlvbiBub2RlRW52TmFtZXMobm9kZUVudjogdW5rbm93bik6IHN0cmluZ1tdIHtcbiAgY29uc3QgbmFtZSA9IHN0cmluZ01vZHVsZS50cmltVG9OdWxsKG5vZGVFbnYpPy50b0xvd2VyQ2FzZSgpO1xuICBpZiAoIW5hbWUgfHwgIS9eW2EtejAtOV8tXSskLy50ZXN0KG5hbWUpKSByZXR1cm4gW107XG4gIGZvciAoY29uc3QgW2Nhbm9uaWNhbCwgYWx0ZXJuYXRpdmVzXSBvZiBPYmplY3QuZW50cmllcyhOT0RFX0VOVl9BTFRFUk5BVElWRVMpKSB7XG4gICAgY29uc3QgbmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdID0gYWx0ZXJuYXRpdmVzO1xuICAgIGlmIChuYW1lID09PSBjYW5vbmljYWwgfHwgbmFtZXMuaW5jbHVkZXMobmFtZSkpIHtcbiAgICAgIHJldHVybiBbLi4ub2JqZWN0LnNlcXVlbmNlKG5hbWUsIGNhbm9uaWNhbCwgYWx0ZXJuYXRpdmVzKS5kaXN0aW5jdCgpXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIFtuYW1lXTtcbn1cblxuZnVuY3Rpb24gam9pbiguLi5wYXJ0czogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gcGFydHNcbiAgICAubWFwKChwYXJ0KSA9PiBwYXJ0LnRyaW0oKSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pXG4gICAgLmpvaW4oXCJfXCIpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBzdHJpbmc6IGBjb25maWd1cmVkYCB3aGVuIG5vbi1lbXB0eSwgZWxzZSB7QGxpbmsgdGV4dH0sIGVsc2UgYHVuZGVmaW5lZGAuXG4gKlxuICogVGhlIGNvZXJjaW9uIHJ1bGVzIGFyZSBkZWxpYmVyYXRlbHkgbG9vc2UgKGBvbmAgLyBgeWVzYCAvIGAxYCBhcmUgYWxsXG4gKiBgdHJ1ZWApIGJlY2F1c2UgdmFsdWVzIG1heSBjb21lIGZyb20gYSBmaWxlIGEgaHVtYW4gdHlwZWQuXG4gKlxuICogQGV4YW1wbGVcbiAqIGNvbmZpZy5zdHJpbmcob3B0aW9ucy5ob3N0LCBcIlNNVFBfSE9TVFwiKTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHN0cmluZyhcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwoY29uZmlndXJlZCkgPz8gdGV4dChpbnB1dCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGJvb2xlYW4gdGhyb3VnaCBgb2JqZWN0LnRvQm9vbGVhbmAuIGB1bmRlZmluZWRgIHdoZW4gbmVpdGhlciBzb3VyY2VcbiAqIGlzIGludGVycHJldGFibGUsIHNvIHRoZSBjYWxsZXIgcGlja3MgYSBkZWZhdWx0IHdpdGggYD8/YC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJvb2xlYW4oXG4gIGNvbmZpZ3VyZWQ6IHVua25vd24sXG4gIGlucHV0OiBDb25maWdLZXksXG4gIG9wdGlvbnM/OiBDb25maWdPcHRpb25zLFxuKTogYm9vbGVhbiB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBvYmplY3QudG9Cb29sZWFuKGNvbmZpZ3VyZWQpID8/IG9iamVjdC50b0Jvb2xlYW4odGV4dChpbnB1dCwgb3B0aW9ucykpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBwb3NpdGl2ZSBudW1iZXIgdGhhdCBtYXkgYmUgZnJhY3Rpb25hbCAoYSBzY29yZSB0aHJlc2hvbGQsIGEgcmF0aW8pLlxuICogVXNlIHtAbGluayBwb3NpdGl2ZUludH0gZm9yIGEgY291bnQsIHBvcnQsIG9yIHRpbWVvdXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwb3NpdGl2ZU51bWJlcihcbiAgY29uZmlndXJlZDogdW5rbm93bixcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgZmFsbGJhY2s6IG51bWJlcixcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBudW1iZXIge1xuICByZXR1cm4gdG9Qb3NpdGl2ZU51bWJlcihjb25maWd1cmVkKSA/PyB0b1Bvc2l0aXZlTnVtYmVyKHRleHQoaW5wdXQsIG9wdGlvbnMpKSA/PyBmYWxsYmFjaztcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgcG9zaXRpdmUgaW50ZWdlciAoYSBwb3J0LCBhIHRpbWVvdXQsIGEgcGFnZSBzaXplKSwgZmxvb3JlZC4gQVxuICogbm9uLW51bWVyaWMgb3Igbm9uLXBvc2l0aXZlIHZhbHVlIGlzIHRyZWF0ZWQgYXMgQUJTRU5UIHJhdGhlciB0aGFuIGZhdGFsIC1cbiAqIHRoZXNlIGFyZSBjZWlsaW5ncyB3aGVyZSBhIHNhbmUgZGVmYXVsdCBiZWF0cyBhIGJvb3QgZmFpbHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc2l0aXZlSW50KFxuICBjb25maWd1cmVkOiB1bmtub3duLFxuICBpbnB1dDogQ29uZmlnS2V5LFxuICBmYWxsYmFjazogbnVtYmVyLFxuICBvcHRpb25zPzogQ29uZmlnT3B0aW9ucyxcbik6IG51bWJlciB7XG4gIGNvbnN0IHJlc29sdmVkID0gcG9zaXRpdmVOdW1iZXIoY29uZmlndXJlZCwgaW5wdXQsIGZhbGxiYWNrLCBvcHRpb25zKTtcbiAgcmV0dXJuIE1hdGguZmxvb3IocmVzb2x2ZWQpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBsaXN0IHRocm91Z2ggYHN0cmluZy5wYXJzZUxpc3RgLCBzbyBhbiBhcnJheSBmcm9tIHR5cGVkIGNvbmZpZyBhbmQgYVxuICogYFwiYSwgYiBjXCJgIHN0cmluZyBub3JtYWxpemUgaWRlbnRpY2FsbHkuIGBbXWAgd2hlbiBuZWl0aGVyIHNvdXJjZSBoYXMgZW50cmllcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3QoXG4gIGNvbmZpZ3VyZWQ6IHN0cmluZyB8IHJlYWRvbmx5IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHwgbnVsbCxcbiAgaW5wdXQ6IENvbmZpZ0tleSxcbiAgdHJhbnNmb3JtPzogKGVudHJ5OiBzdHJpbmcpID0+IHN0cmluZyxcbiAgb3B0aW9ucz86IENvbmZpZ09wdGlvbnMsXG4pOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGZyb21Db25maWcgPSBzdHJpbmdNb2R1bGUucGFyc2VMaXN0KGNvbmZpZ3VyZWQsIHRyYW5zZm9ybSk7XG4gIHJldHVybiBmcm9tQ29uZmlnLmxlbmd0aCA+IDBcbiAgICA/IGZyb21Db25maWdcbiAgICA6IHN0cmluZ01vZHVsZS5wYXJzZUxpc3QodGV4dChpbnB1dCwgb3B0aW9ucyksIHRyYW5zZm9ybSk7XG59XG5cbmZ1bmN0aW9uIHRvUG9zaXRpdmVOdW1iZXIodmFsdWU6IHVua25vd24pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICBjb25zdCBwYXJzZWQgPSBvYmplY3QudG9OdW1iZXIodmFsdWUpO1xuICByZXR1cm4gcGFyc2VkICE9PSB1bmRlZmluZWQgJiYgcGFyc2VkID4gMCA/IHBhcnNlZCA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBUaGUgRGF0YWJyaWNrcyBidW5kbGUgb3V0cHV0IGZvciBgY3dkYCAtIGBkYXRhYnJpY2tzIGJ1bmRsZSB2YWxpZGF0ZSAtLW91dHB1dFxuICoganNvbmAgcnVuIGZyb20gdGhlIGRpcmVjdG9yeSBob2xkaW5nIGBkYXRhYnJpY2tzLnltbGAsIHdpdGggdGhlIGNvbmZpZyBmaWxlJ3NcbiAqIHBhdGguIEEgbm9uLXplcm8gdmFsaWRhdGlvbiBtYXkgc3RpbGwgcmV0dXJuIHBhcnRpYWwgSlNPTiB3aXRoIHVzYWJsZVxuICogdmFyaWFibGVzLiBgdW5kZWZpbmVkYCB3aGVuIHRoZXJlIGlzIG5vIGJ1bmRsZSwgdGhlIENMSSBwcm9kdWNlcyBubyBKU09OLCBvclxuICogdGhpcyBwcm9jZXNzIGlzIGEgZGVwbG95ZWQgRGF0YWJyaWNrcyBBcHAuXG4gKlxuICogQ2FjaGVkIHBlciB3b3JraW5nIGRpcmVjdG9yeSBhbmQgYERBVEFCUklDS1NfQ09ORklHX1BST0ZJTEVgIHRocm91Z2hcbiAqIHtAbGluayBjb250ZXh0LmNhY2hlZH0sIHNvIGNoYW5naW5nIGVpdGhlciBjYW5ub3QgcmV0dXJuIGFub3RoZXIgY29udGV4dCdzXG4gKiBidW5kbGUuIEEgbG9va3VwIGZvciBzb21lIG90aGVyIGRpcmVjdG9yeSBpcyBub3QgY2FjaGVkIGF0IGFsbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1bmRsZUZpbGUoY3dkPzogc3RyaW5nIHwgbnVsbCk6IENvbmZpZ0ZpbGUgfCB1bmRlZmluZWQge1xuICBjb25zdCBwcm9maWxlID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocHJvY2Vzcy5lbnYuREFUQUJSSUNLU19DT05GSUdfUFJPRklMRSk7XG4gIHJldHVybiBjb250ZXh0LmNhY2hlZChcbiAgICBbXCJjb25maWdcIiwgXCJidW5kbGVcIiwgcHJvZmlsZSA/PyBcIlwiXSxcbiAgICAocmVzb2x2ZWQpID0+IGxvYWRCdW5kbGVGaWxlKHJlc29sdmVkID8/IFwiLlwiLCBwcm9maWxlKSxcbiAgICBjd2QsXG4gICk7XG59XG5cbi8qKlxuICogVGhlIHNpbmdsZSBBcHAncyBsaXRlcmFsIGBjb25maWcuZW52YCBlbnRyaWVzLCBmbGF0dGVuZWQgdG8gYG5hbWUgLT4gdmFsdWVgLlxuICpcbiAqIEEgYHZhbHVlX2Zyb21gIGVudHJ5IG5hbWVzIGEgYnVuZGxlIHJlc291cmNlIHdob3NlIGlkIGlzIGtub3duIGFmdGVyXG4gKiBkZXBsb3ltZW50LCBhbmQgcmVhZGluZyBpdCBuZWVkcyB0aGUgcmVzb3VyY2Ugdm9jYWJ1bGFyeSB0aGlzIG1vZHVsZVxuICogZGVsaWJlcmF0ZWx5IGRvZXMgbm90IGhhdmUgLSBub2RlLWFwcGtpdCByZXNvbHZlcyB0aG9zZSBhZ2FpbnN0IGl0cyBleHRlbmRlZFxuICoge0BsaW5rIGJ1bmRsZVJlc291cmNlU2NoZW1hfS4gQW4gYGFwcHNgIGJsb2NrIHdpdGggbW9yZSB0aGFuIG9uZSBhcHAgaXNcbiAqIGFtYmlndW91cyAobm90aGluZyBoZXJlIHNheXMgd2hpY2ggYXBwIHRoaXMgcHJvY2VzcyBpcyksIHNvIGl0IHlpZWxkcyBub3RoaW5nXG4gKiByYXRoZXIgdGhhbiBhIGd1ZXNzLlxuICovXG5mdW5jdGlvbiBidW5kbGVBcHAoaW5wdXQ6IHVua25vd24pOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgY29uc3QgcGFyc2VkID0gYnVuZGxlQXBwc1NjaGVtYS5zYWZlUGFyc2UoaW5wdXQpO1xuICBpZiAoIXBhcnNlZC5zdWNjZXNzKSByZXR1cm4ge307XG4gIGNvbnN0IGFwcHMgPSBwYXJzZWQuZGF0YS5yZXNvdXJjZXM/LmFwcHM7XG4gIGlmICghYXBwcykgcmV0dXJuIHt9O1xuICBjb25zdCBuYW1lcyA9IE9iamVjdC5rZXlzKGFwcHMpO1xuICBpZiAobmFtZXMubGVuZ3RoICE9PSAxKSByZXR1cm4ge307XG4gIGNvbnN0IGVudHJpZXMgPSBhcHBzW25hbWVzWzBdIV0/LmNvbmZpZz8uZW52ID8/IFtdO1xuICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgZm9yIChjb25zdCBlbnRyeSBvZiBlbnRyaWVzKSB7XG4gICAgaWYgKCFlbnRyeS5uYW1lKSBjb250aW51ZTtcbiAgICBjb25zdCB2YWx1ZSA9IHJlc29sdmVkU3RyaW5nKGVudHJ5LnZhbHVlKTtcbiAgICBpZiAodmFsdWUgIT09IG51bGwpIHJlc3VsdFtlbnRyeS5uYW1lXSA9IHZhbHVlO1xuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogUm9vdCBidW5kbGUgdmFyaWFibGVzIGZsYXR0ZW5lZCB0byBlbnZpcm9ubWVudC1zdHlsZSBgTkFNRSAtPiB2YWx1ZWAgZW50cmllcy5cbiAqXG4gKiBgZGF0YWJyaWNrcyBidW5kbGUgdmFsaWRhdGVgIHJlc29sdmVzIGVhY2ggdmFyaWFibGUgdG8gYHZhbHVlYDsgYGRlZmF1bHRgIGlzXG4gKiByZXRhaW5lZCBhcyBhIGZhbGxiYWNrIGZvciBwYXJzZWQgYnVuZGxlIGRhdGEgdGhhdCBoYXMgbm90IGJlZW4gZnVsbHlcbiAqIHJlc29sdmVkLiBOYW1lcyBhcmUgbm9ybWFsaXplZCBzbyBhIGJ1bmRsZSB2YXJpYWJsZSBzdWNoIGFzXG4gKiBgdHVubmVsX3B1YmxpY19kb21haW5gIGFuc3dlcnMgYSBsb29rdXAgZm9yIGBUVU5ORUxfUFVCTElDX0RPTUFJTmAuXG4gKi9cbmZ1bmN0aW9uIGJ1bmRsZVZhcmlhYmxlcyhpbnB1dDogdW5rbm93bik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBwYXJzZWQgPSBidW5kbGVWYXJpYWJsZXNTY2hlbWEuc2FmZVBhcnNlKGlucHV0KTtcbiAgaWYgKCFwYXJzZWQuc3VjY2VzcykgcmV0dXJuIHt9O1xuICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgZm9yIChjb25zdCBbbmFtZSwgdmFyaWFibGVdIG9mIE9iamVjdC5lbnRyaWVzKHBhcnNlZC5kYXRhLnZhcmlhYmxlcyA/PyB7fSkpIHtcbiAgICBjb25zdCBrZXkgPSBbLi4uc3RyaW5nTW9kdWxlLnRva2VuaXplKG5hbWUpXS5qb2luKFwiX1wiKS50b1VwcGVyQ2FzZSgpO1xuICAgIGNvbnN0IHZhbHVlID0gcmVzb2x2ZWRTdHJpbmcodmFyaWFibGUudmFsdWUpID8/IHJlc29sdmVkU3RyaW5nKHZhcmlhYmxlLmRlZmF1bHQpO1xuICAgIGlmIChrZXkgJiYgdmFsdWUgIT09IG51bGwpIHJlc3VsdFtrZXldID0gdmFsdWU7XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqIEEgbm9uLWVtcHR5IGJ1bmRsZSB2YWx1ZSB3aXRoIGV2ZXJ5IGAkey4uLn1gIGludGVycG9sYXRpb24gcmVzb2x2ZWQuICovXG5mdW5jdGlvbiByZXNvbHZlZFN0cmluZyh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBwYXJzZWQgPSBidW5kbGVWYWx1ZS5zYWZlUGFyc2UodmFsdWUpO1xuICByZXR1cm4gcGFyc2VkLnN1Y2Nlc3MgPyBwYXJzZWQuZGF0YSA6IG51bGw7XG59XG5cbi8qKiBQYXJzZWQgYC5lbnZgIGZvciBgY3dkYCwgb3IgYHt9YC4gQ2FjaGVkIHBlciB3b3JraW5nIGRpcmVjdG9yeS4gKi9cbmZ1bmN0aW9uIGRvdGVudihjd2Q/OiBzdHJpbmcgfCBudWxsKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGVudmlyb25tZW50cyA9IG5vZGVFbnZOYW1lcyhwcm9jZXNzLmVudi5OT0RFX0VOVik7XG4gIHJldHVybiBjb250ZXh0LmNhY2hlZChcbiAgICBbXCJjb25maWdcIiwgXCJkb3RlbnZcIiwgLi4uZW52aXJvbm1lbnRzXSxcbiAgICAocmVzb2x2ZWQpID0+IGxvYWREb3RlbnYocmVzb2x2ZWQgPz8gXCIuXCIsIGVudmlyb25tZW50cyksXG4gICAgY3dkLFxuICApO1xufVxuXG4vKipcbiAqIE1hcHMgZm9yIG9uZSBzb3VyY2UgaW4gcHJlY2VkZW5jZSBvcmRlci4gQnVuZGxlIEFwcCBjb25maWcgYW5kIHJvb3QgdmFyaWFibGVzXG4gKiBzdGF5IHNlcGFyYXRlIHNvIGEgZmlyc3QtbWF0Y2ggbG9va3VwIGRvZXMgbm90IHBhcnNlIHZhcmlhYmxlcyBhZnRlciBhbiBBcHBcbiAqIHZhbHVlIHJlc29sdmVzLlxuICovXG5mdW5jdGlvbiByZWFkKFxuICBzb3VyY2U6IENvbmZpZ1NvdXJjZSxcbiAgY3dkPzogc3RyaW5nLFxuKTogb2JqZWN0LlNlcXVlbmNlPFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4+IHtcbiAgcmV0dXJuIG9iamVjdC5zZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCk6IEdlbmVyYXRvcjxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+PiB7XG4gICAgICBzd2l0Y2ggKHNvdXJjZSkge1xuICAgICAgICBjYXNlIFwiZW52XCI6XG4gICAgICAgICAgeWllbGQgcHJvY2Vzcy5lbnY7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgXCJkb3RlbnZcIjpcbiAgICAgICAgICB5aWVsZCBkb3RlbnYoY3dkKTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBcImJ1bmRsZVwiOiB7XG4gICAgICAgICAgY29uc3QgYnVuZGxlID0gYnVuZGxlRmlsZShjd2QpO1xuICAgICAgICAgIGlmIChidW5kbGUpIHtcbiAgICAgICAgICAgIHlpZWxkIGJ1bmRsZUFwcChidW5kbGUuZGF0YSk7XG4gICAgICAgICAgICB5aWVsZCBidW5kbGVWYXJpYWJsZXMoYnVuZGxlLmRhdGEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIExvY2F0ZSBgbmFtZXNgIGZyb20gYGN3ZGAgb3V0d2FyZC4gYGN3ZGAgaXRzZWxmIGlzIGNoZWNrZWQgYmVmb3JlIHRoZVxuICogZGlzY292ZXJlZCBwcm9qZWN0IHJvb3RzIHNvIGEgcGFja2FnZS1sb2NhbCBmaWxlIHdpbnMgb3ZlciB0aGUgd29ya3NwYWNlJ3MuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDb25maWdGaWxlKGN3ZDogc3RyaW5nLCBuYW1lczogcmVhZG9ubHkgc3RyaW5nW10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBpZiAoaXNEYXRhYnJpY2tzQXBwRW52KCkpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IHN0YXJ0ID0gcmVzb2x2ZShjd2QpO1xuICBjb25zdCByb290ID0gcmVzb2x2ZVByb2plY3RSb290KHN0YXJ0KTtcbiAgY29uc3QgcGF0aEZyb21Sb290ID0gcm9vdCA/IHJlbGF0aXZlKHJvb3QsIHN0YXJ0KSA6IHVuZGVmaW5lZDtcbiAgY29uc3QgYm91bmRhcnkgPVxuICAgIHJvb3QgJiZcbiAgICBwYXRoRnJvbVJvb3QgIT09IHVuZGVmaW5lZCAmJlxuICAgICFpc0Fic29sdXRlKHBhdGhGcm9tUm9vdCkgJiZcbiAgICBwYXRoRnJvbVJvb3QgIT09IFwiLi5cIiAmJlxuICAgICFwYXRoRnJvbVJvb3Quc3RhcnRzV2l0aChgLi4ke3NlcH1gKVxuICAgICAgPyByb290XG4gICAgICA6IHVuZGVmaW5lZDtcbiAgZm9yIChsZXQgZGlyID0gc3RhcnQ7IDsgZGlyID0gZGlybmFtZShkaXIpKSB7XG4gICAgZm9yIChjb25zdCBuYW1lIG9mIG5hbWVzKSB7XG4gICAgICBjb25zdCBwYXRoID0gcmVzb2x2ZShkaXIsIG5hbWUpO1xuICAgICAgaWYgKHN0YXRTeW5jKHBhdGgpPy5pc0ZpbGUoKSkgcmV0dXJuIHBhdGg7XG4gICAgfVxuICAgIGlmIChib3VuZGFyeSA9PT0gdW5kZWZpbmVkIHx8IGRpciA9PT0gYm91bmRhcnkpIGJyZWFrO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxvYWREb3RlbnYoXG4gIGN3ZDogc3RyaW5nLFxuICBlbnZpcm9ubWVudHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuKTogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IG5hbWVzID0gWy4uLmVudmlyb25tZW50cy5tYXAoKG5hbWUpID0+IGAke0RPVEVOVl9GSUxFX05BTUV9LiR7bmFtZX1gKSwgRE9URU5WX0ZJTEVfTkFNRV07XG4gIGNvbnN0IHBhdGggPSBmaW5kQ29uZmlnRmlsZShjd2QsIG5hbWVzKTtcbiAgaWYgKCFwYXRoKSByZXR1cm4ge307XG4gIHRyeSB7XG4gICAgcmV0dXJuIHBhcnNlRW52KHJlYWRGaWxlU3luYyhwYXRoLCBcInV0ZjhcIikpO1xuICB9IGNhdGNoIHtcbiAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byByZWFkIGRvdGVudiBmaWxlXCIsIHsgcGF0aCB9KTtcbiAgICByZXR1cm4ge307XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9hZEJ1bmRsZUZpbGUoY3dkOiBzdHJpbmcsIHByb2ZpbGU6IHN0cmluZyB8IG51bGwpOiBDb25maWdGaWxlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgcGF0aCA9IGZpbmRDb25maWdGaWxlKGN3ZCwgQlVORExFX0ZJTEVfTkFNRVMpO1xuICBpZiAoIXBhdGgpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGFyZ3MgPSBbXG4gICAgXCJidW5kbGVcIixcbiAgICBcInZhbGlkYXRlXCIsXG4gICAgXCItLW91dHB1dFwiLFxuICAgIFwianNvblwiLFxuICAgIC4uLihwcm9maWxlID09PSBudWxsID8gW10gOiBbXCItLXByb2ZpbGVcIiwgcHJvZmlsZV0pLFxuICBdO1xuICBjb25zdCByZXN1bHQgPSBzcGF3blN5bmMoXCJkYXRhYnJpY2tzXCIsIGFyZ3MsIHtcbiAgICBjd2Q6IHJlc29sdmUocGF0aCwgXCIuLlwiKSxcbiAgICBlbmNvZGluZzogXCJ1dGY4XCIsXG4gICAgc3RkaW86IFtcImlnbm9yZVwiLCBcInBpcGVcIiwgXCJwaXBlXCJdLFxuICB9KTtcbiAgY29uc3Qgb3V0cHV0ID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocmVzdWx0LnN0ZG91dCk7XG4gIGNvbnN0IGVycm9yID0gc3RyaW5nTW9kdWxlLnRyaW1Ub051bGwocmVzdWx0LnN0ZGVycik7XG4gIGlmIChvdXRwdXQgPT09IG51bGwpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJidW5kbGUgdmFsaWRhdGUgcHJvZHVjZWQgbm8gSlNPTlwiLCB7IHBhdGgsIHN0YXR1czogcmVzdWx0LnN0YXR1cywgZXJyb3IgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuICBjb25zdCBkYXRhID0ganNvbi5wYXJzZVJlY29yZChvdXRwdXQpO1xuICBpZiAoIWRhdGEpIHtcbiAgICBsb2dnZXIud2FybihcImZhaWxlZCB0byBwYXJzZSBidW5kbGUgdmFsaWRhdGUgb3V0cHV0XCIsIHsgcGF0aCwgc3RhdHVzOiByZXN1bHQuc3RhdHVzIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbiAgaWYgKHJlc3VsdC5zdGF0dXMgIT09IDApIHtcbiAgICBsb2dnZXIuZGVidWcoXCJ1c2luZyBwYXJ0aWFsIGJ1bmRsZSBvdXRwdXRcIiwgeyBwYXRoLCBzdGF0dXM6IHJlc3VsdC5zdGF0dXMsIGVycm9yIH0pO1xuICB9XG4gIHJldHVybiB7IHBhdGgsIGRhdGEgfTtcbn1cbiJdfQ==
|
|
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.87",
|
|
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.87",
|
|
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
|
@@ -14,10 +14,34 @@
|
|
|
14
14
|
* the spawn happens once per working directory and a `cwd` change misses
|
|
15
15
|
* rather than returning another project's config.
|
|
16
16
|
*
|
|
17
|
-
* Inside a deployed Databricks App both file sources are skipped
|
|
17
|
+
* Inside a deployed Databricks App both file sources are skipped by default
|
|
18
18
|
* ({@link isDatabricksAppEnv}): the platform has already turned them into real
|
|
19
19
|
* environment variables, there is no bundle to validate, and the `databricks`
|
|
20
|
-
* CLI is not on the image.
|
|
20
|
+
* CLI is not on the image. Boolean environment overrides can force either file
|
|
21
|
+
* source on or off when a tool needs different behavior.
|
|
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.
|
|
21
45
|
*
|
|
22
46
|
* Node-only (`child_process`, `fs`, `process`).
|
|
23
47
|
*
|
|
@@ -26,21 +50,29 @@
|
|
|
26
50
|
|
|
27
51
|
import { spawnSync } from "node:child_process";
|
|
28
52
|
import { readFileSync } from "node:fs";
|
|
53
|
+
import { createRequire } from "node:module";
|
|
29
54
|
import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
|
|
30
55
|
import { parseEnv } from "node:util";
|
|
31
|
-
import {
|
|
56
|
+
import {
|
|
57
|
+
context,
|
|
58
|
+
functionModule,
|
|
59
|
+
json,
|
|
60
|
+
log,
|
|
61
|
+
object,
|
|
62
|
+
string as stringModule,
|
|
63
|
+
} from "@dbx-tools/shared-core";
|
|
32
64
|
import { z } from "zod";
|
|
33
65
|
import { statSync } from "./file.ts";
|
|
34
66
|
import { root as resolveProjectRoot } from "./project.ts";
|
|
35
67
|
|
|
36
68
|
const logger = log.logger("config");
|
|
37
69
|
|
|
38
|
-
type ConfigKey = string | readonly string[];
|
|
70
|
+
export type ConfigKey = string | readonly string[];
|
|
39
71
|
|
|
40
72
|
/** Where a value may come from, consulted in the order given. */
|
|
41
|
-
type ConfigSource = "env" | "dotenv" | "bundle";
|
|
73
|
+
export type ConfigSource = "env" | "dotenv" | "bundle";
|
|
42
74
|
|
|
43
|
-
interface ConfigOptions {
|
|
75
|
+
export interface ConfigOptions {
|
|
44
76
|
/**
|
|
45
77
|
* Outermost namespaces tried before each key. Defaults to `DBX_TOOLS`.
|
|
46
78
|
*/
|
|
@@ -78,6 +110,41 @@ const NODE_ENV_ALTERNATIVES = {
|
|
|
78
110
|
/** Highest valid TCP port number. */
|
|
79
111
|
export const MAX_TCP_PORT = 65_535;
|
|
80
112
|
|
|
113
|
+
/** Boolean environment override for {@link isDatabricksAppEnv}. */
|
|
114
|
+
export const DATABRICKS_APP_ENV_KEY = "DBX_TOOLS_DATABRICKS_APP_ENV";
|
|
115
|
+
|
|
116
|
+
/** Boolean environment override for project `.env` reads. */
|
|
117
|
+
export const CONFIG_DOTENV_KEY = "DBX_TOOLS_CONFIG_DOTENV";
|
|
118
|
+
|
|
119
|
+
/** Boolean environment override for Databricks bundle reads. */
|
|
120
|
+
export const CONFIG_BUNDLE_KEY = "DBX_TOOLS_CONFIG_BUNDLE";
|
|
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
|
+
|
|
81
148
|
/** Exact process-environment lookup for callers that do not read local config files. */
|
|
82
149
|
export const ENV_ONLY = { scope: [] as const, sources: "env" as const };
|
|
83
150
|
|
|
@@ -104,11 +171,6 @@ export const bundleEnvEntrySchema = z.object({
|
|
|
104
171
|
value_from: bundleValue.optional(),
|
|
105
172
|
});
|
|
106
173
|
|
|
107
|
-
const bundleVariableSchema = z.object({
|
|
108
|
-
default: z.string().optional(),
|
|
109
|
-
value: z.string().optional(),
|
|
110
|
-
});
|
|
111
|
-
|
|
112
174
|
export const bundleAppSchema = z.object({
|
|
113
175
|
name: bundleValue.optional(),
|
|
114
176
|
source_code_path: z.string().optional(),
|
|
@@ -120,16 +182,19 @@ const bundleAppsSchema = z.object({
|
|
|
120
182
|
resources: z.object({ apps: z.record(z.string(), bundleAppSchema).optional() }).optional(),
|
|
121
183
|
});
|
|
122
184
|
|
|
123
|
-
const bundleVariablesSchema = z.object({
|
|
124
|
-
variables: z.record(z.string(), bundleVariableSchema).optional(),
|
|
125
|
-
});
|
|
126
|
-
|
|
127
185
|
/**
|
|
128
186
|
* Detect a Databricks App runtime from its required name, host, and port.
|
|
187
|
+
*
|
|
188
|
+
* `DBX_TOOLS_DATABRICKS_APP_ENV` takes precedence when it contains a recognized
|
|
189
|
+
* boolean value. This lets local tools emulate the deployed runtime (`true`) or
|
|
190
|
+
* lets unusual deployed processes retain local config lookup (`false`). An
|
|
191
|
+
* absent or unrecognized override falls back to structural detection.
|
|
129
192
|
*/
|
|
130
193
|
export function isDatabricksAppEnv(
|
|
131
194
|
source: Record<string, string | undefined> = process.env,
|
|
132
195
|
): boolean {
|
|
196
|
+
const override = object.toBoolean(source[DATABRICKS_APP_ENV_KEY]);
|
|
197
|
+
if (override !== undefined) return override;
|
|
133
198
|
const appName = source.DATABRICKS_APP_NAME?.trim();
|
|
134
199
|
const host = source.DATABRICKS_HOST?.trim();
|
|
135
200
|
const port = source.DATABRICKS_APP_PORT?.trim();
|
|
@@ -321,21 +386,48 @@ function toPositiveNumber(value: unknown): number | undefined {
|
|
|
321
386
|
/**
|
|
322
387
|
* The Databricks bundle output for `cwd` - `databricks bundle validate --output
|
|
323
388
|
* json` run from the directory holding `databricks.yml`, with the config file's
|
|
324
|
-
* path. A non-zero validation may still return partial JSON with usable
|
|
325
|
-
*
|
|
326
|
-
*
|
|
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.
|
|
327
400
|
*
|
|
328
|
-
* Cached per working
|
|
329
|
-
* {@link context.cached}, so
|
|
330
|
-
*
|
|
401
|
+
* Cached once per resolved working-directory context and
|
|
402
|
+
* `DATABRICKS_CONFIG_PROFILE` through {@link context.cached}, so repeated
|
|
403
|
+
* lookups do not rerun validation and changing either cannot return another
|
|
404
|
+
* context's bundle.
|
|
331
405
|
*/
|
|
332
406
|
export function bundleFile(cwd?: string | null): ConfigFile | undefined {
|
|
407
|
+
const production = process.env.NODE_ENV?.trim().toLowerCase() === "production";
|
|
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
|
+
}
|
|
333
417
|
const profile = stringModule.trimToNull(process.env.DATABRICKS_CONFIG_PROFILE);
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
(resolved) => loadBundleFile(resolved ?? ".", profile),
|
|
337
|
-
cwd,
|
|
418
|
+
const file = cachedConfig(["bundle", profile ?? ""], cwd, (resolved) =>
|
|
419
|
+
loadBundleFile(resolved, profile),
|
|
338
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;
|
|
339
431
|
}
|
|
340
432
|
|
|
341
433
|
/**
|
|
@@ -347,8 +439,23 @@ export function bundleFile(cwd?: string | null): ConfigFile | undefined {
|
|
|
347
439
|
* {@link bundleResourceSchema}. An `apps` block with more than one app is
|
|
348
440
|
* ambiguous (nothing here says which app this process is), so it yields nothing
|
|
349
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.
|
|
350
447
|
*/
|
|
351
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> {
|
|
352
459
|
const parsed = bundleAppsSchema.safeParse(input);
|
|
353
460
|
if (!parsed.success) return {};
|
|
354
461
|
const apps = parsed.data.resources?.apps;
|
|
@@ -366,23 +473,69 @@ function bundleApp(input: unknown): Record<string, string> {
|
|
|
366
473
|
}
|
|
367
474
|
|
|
368
475
|
/**
|
|
369
|
-
*
|
|
476
|
+
* Whether `@databricks/appkit` can be RESOLVED from this process, cached for its
|
|
477
|
+
* lifetime.
|
|
370
478
|
*
|
|
371
|
-
*
|
|
372
|
-
*
|
|
373
|
-
*
|
|
374
|
-
*
|
|
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.
|
|
375
484
|
*/
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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;
|
|
384
494
|
}
|
|
385
|
-
|
|
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);
|
|
386
539
|
}
|
|
387
540
|
|
|
388
541
|
/** A non-empty bundle value with every `${...}` interpolation resolved. */
|
|
@@ -391,16 +544,26 @@ function resolvedString(value: unknown): string | null {
|
|
|
391
544
|
return parsed.success ? parsed.data : null;
|
|
392
545
|
}
|
|
393
546
|
|
|
394
|
-
/** Parsed `.env` for `cwd`, or `{}`.
|
|
547
|
+
/** Parsed `.env` for `cwd`, or `{}`. Read once per resolved context. */
|
|
395
548
|
function dotenv(cwd?: string | null): Record<string, string | undefined> {
|
|
549
|
+
if (!fileSourceEnabled(CONFIG_DOTENV_KEY)) return {};
|
|
396
550
|
const environments = nodeEnvNames(process.env.NODE_ENV);
|
|
397
|
-
return
|
|
398
|
-
|
|
399
|
-
(resolved) => loadDotenv(resolved ?? ".", environments),
|
|
400
|
-
cwd,
|
|
551
|
+
return cachedConfig(["dotenv", ...environments], cwd, (resolved) =>
|
|
552
|
+
loadDotenv(resolved, environments),
|
|
401
553
|
);
|
|
402
554
|
}
|
|
403
555
|
|
|
556
|
+
/** Cache every target directory separately within the active process context. */
|
|
557
|
+
function cachedConfig<T>(
|
|
558
|
+
name: readonly string[],
|
|
559
|
+
cwd: string | null | undefined,
|
|
560
|
+
loader: (resolved: string) => T,
|
|
561
|
+
): T {
|
|
562
|
+
const active = context.getContext() ?? "";
|
|
563
|
+
const resolved = resolve(cwd ?? ".");
|
|
564
|
+
return context.cached(["config", active, resolved, ...name], () => loader(resolved));
|
|
565
|
+
}
|
|
566
|
+
|
|
404
567
|
/**
|
|
405
568
|
* Maps for one source in precedence order. Bundle App config and root variables
|
|
406
569
|
* stay separate so a first-match lookup does not parse variables after an App
|
|
@@ -421,10 +584,7 @@ function read(
|
|
|
421
584
|
break;
|
|
422
585
|
case "bundle": {
|
|
423
586
|
const bundle = bundleFile(cwd);
|
|
424
|
-
if (bundle)
|
|
425
|
-
yield bundleApp(bundle.data);
|
|
426
|
-
yield bundleVariables(bundle.data);
|
|
427
|
-
}
|
|
587
|
+
if (bundle) yield bundleApp(bundle.data);
|
|
428
588
|
break;
|
|
429
589
|
}
|
|
430
590
|
}
|
|
@@ -437,7 +597,6 @@ function read(
|
|
|
437
597
|
* discovered project roots so a package-local file wins over the workspace's.
|
|
438
598
|
*/
|
|
439
599
|
function findConfigFile(cwd: string, names: readonly string[]): string | undefined {
|
|
440
|
-
if (isDatabricksAppEnv()) return undefined;
|
|
441
600
|
const start = resolve(cwd);
|
|
442
601
|
const root = resolveProjectRoot(start);
|
|
443
602
|
const pathFromRoot = root ? relative(root, start) : undefined;
|
|
@@ -459,6 +618,11 @@ function findConfigFile(cwd: string, names: readonly string[]): string | undefin
|
|
|
459
618
|
return undefined;
|
|
460
619
|
}
|
|
461
620
|
|
|
621
|
+
/** A recognized source override, else the caller's automatic default. */
|
|
622
|
+
function fileSourceEnabled(key: string, fallback: boolean = !isDatabricksAppEnv()): boolean {
|
|
623
|
+
return object.toBoolean(process.env[key]) ?? fallback;
|
|
624
|
+
}
|
|
625
|
+
|
|
462
626
|
function loadDotenv(
|
|
463
627
|
cwd: string,
|
|
464
628
|
environments: readonly string[],
|