@dbx-tools/cli-tunnel 0.6.58 → 0.6.59
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 +7 -7
- package/lib/src/app.d.ts +12 -15
- package/lib/src/app.js +18 -28
- package/package.json +6 -6
- package/src/app.ts +17 -26
package/README.md
CHANGED
|
@@ -165,13 +165,13 @@ Resolution order:
|
|
|
165
165
|
it wraps reloads. On the default in-memory cache the key is per-process, the
|
|
166
166
|
same as having no secret at all.
|
|
167
167
|
|
|
168
|
-
Getting that persistence is not automatic, and the gate does the work at boot
|
|
169
|
-
it
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
`the gate cache stays in memory`).
|
|
174
|
-
get the persistent path.
|
|
168
|
+
Getting that persistence is not automatic, and the gate does the work at boot
|
|
169
|
+
via `lakebaseResolver.applyLakebaseEnv()`: it turns `LAKEBASE_ENDPOINT` into the
|
|
170
|
+
`PGHOST` / `PGDATABASE` / `PGUSER` the cache's pool also needs. Without them
|
|
171
|
+
AppKit cannot build the pool, silently uses an in-memory cache, and every
|
|
172
|
+
redeploy signs everyone out - so the startup log says which one you got
|
|
173
|
+
(`lakebase resolved for the gate cache`, or `the gate cache stays in memory`).
|
|
174
|
+
Bind a `postgres` resource to the app to get the persistent path.
|
|
175
175
|
|
|
176
176
|
3. **An ephemeral per-process key**, when there is no secret and no reachable
|
|
177
177
|
cache. Sessions do not survive a restart, but the gate still serves: the key
|
package/lib/src/app.d.ts
CHANGED
|
@@ -96,22 +96,19 @@ export declare function codeEmailPreview(code: string, opts: CodeCopy): string;
|
|
|
96
96
|
* chooses PERSISTENT storage instead of memory.
|
|
97
97
|
*
|
|
98
98
|
* This is what makes the gate's session signing key and outstanding one-time
|
|
99
|
-
* codes survive a restart
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* developer on a PAT, with no `DATABRICKS_CLIENT_ID`) is always missing. Without
|
|
108
|
-
* all four the pool cannot be built, the cache silently degrades to in-memory, and
|
|
109
|
-
* every redeploy signs out every user (the exact symptom this exists to prevent).
|
|
99
|
+
* codes survive a restart. `applyLakebaseEnv` is the SHARED helper AppKit
|
|
100
|
+
* auto-configuration uses, so the gate gets exactly the env a pool needs -
|
|
101
|
+
* `LAKEBASE_ENDPOINT`, `PGHOST`, `PGDATABASE`, and `PGUSER` - rather than a
|
|
102
|
+
* hand-rolled subset. All four matter: `createLakebasePool()` throws without any
|
|
103
|
+
* one of them, and a Databricks App `postgres` resource binding supplies only the
|
|
104
|
+
* first. Without them the pool cannot be built, the cache silently degrades to
|
|
105
|
+
* in-memory, and every redeploy signs out every user (the exact symptom this
|
|
106
|
+
* exists to prevent).
|
|
110
107
|
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
108
|
+
* It is called here rather than left to `createApp`'s `autoConfigure` because that
|
|
109
|
+
* gates on a `lakebase()` plugin being registered - and this app registers none,
|
|
110
|
+
* having no server to mount Lakebase routes on. Calling the helper directly also
|
|
111
|
+
* lets the gate be stricter than `autoConfigure` is:
|
|
115
112
|
*
|
|
116
113
|
* - It runs ONLY when a Lakebase env var is present. A tunnel is a wrapper
|
|
117
114
|
* around someone else's app and must not invent infrastructure, so with
|
package/lib/src/app.js
CHANGED
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
*
|
|
25
25
|
* @module
|
|
26
26
|
*/
|
|
27
|
-
import { getUsernameWithApiLookup } from "@databricks/appkit";
|
|
28
27
|
import { createApp as createAppNs, lakebaseResolver } from "@dbx-tools/appkit";
|
|
29
28
|
import { brand as nodeBrand } from "@dbx-tools/core";
|
|
30
29
|
import { brand as emailBrand, email, sender, transport } from "@dbx-tools/email";
|
|
@@ -126,7 +125,7 @@ export function codeEmailPreview(code, opts) {
|
|
|
126
125
|
return `${opts.message} ${code}`;
|
|
127
126
|
}
|
|
128
127
|
const { createApp } = createAppNs;
|
|
129
|
-
const {
|
|
128
|
+
const { applyLakebaseEnv } = lakebaseResolver;
|
|
130
129
|
const { resolveSystemSenderAddress } = sender;
|
|
131
130
|
const { getEmailRuntime, sendEmail } = transport;
|
|
132
131
|
const { emailBrandFromContext } = emailBrand;
|
|
@@ -148,22 +147,19 @@ const LAKEBASE_RESOLVE_TIMEOUT_MS = 60_000;
|
|
|
148
147
|
* chooses PERSISTENT storage instead of memory.
|
|
149
148
|
*
|
|
150
149
|
* This is what makes the gate's session signing key and outstanding one-time
|
|
151
|
-
* codes survive a restart
|
|
152
|
-
*
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
*
|
|
159
|
-
* developer on a PAT, with no `DATABRICKS_CLIENT_ID`) is always missing. Without
|
|
160
|
-
* all four the pool cannot be built, the cache silently degrades to in-memory, and
|
|
161
|
-
* every redeploy signs out every user (the exact symptom this exists to prevent).
|
|
150
|
+
* codes survive a restart. `applyLakebaseEnv` is the SHARED helper AppKit
|
|
151
|
+
* auto-configuration uses, so the gate gets exactly the env a pool needs -
|
|
152
|
+
* `LAKEBASE_ENDPOINT`, `PGHOST`, `PGDATABASE`, and `PGUSER` - rather than a
|
|
153
|
+
* hand-rolled subset. All four matter: `createLakebasePool()` throws without any
|
|
154
|
+
* one of them, and a Databricks App `postgres` resource binding supplies only the
|
|
155
|
+
* first. Without them the pool cannot be built, the cache silently degrades to
|
|
156
|
+
* in-memory, and every redeploy signs out every user (the exact symptom this
|
|
157
|
+
* exists to prevent).
|
|
162
158
|
*
|
|
163
|
-
*
|
|
164
|
-
*
|
|
165
|
-
*
|
|
166
|
-
*
|
|
159
|
+
* It is called here rather than left to `createApp`'s `autoConfigure` because that
|
|
160
|
+
* gates on a `lakebase()` plugin being registered - and this app registers none,
|
|
161
|
+
* having no server to mount Lakebase routes on. Calling the helper directly also
|
|
162
|
+
* lets the gate be stricter than `autoConfigure` is:
|
|
167
163
|
*
|
|
168
164
|
* - It runs ONLY when a Lakebase env var is present. A tunnel is a wrapper
|
|
169
165
|
* around someone else's app and must not invent infrastructure, so with
|
|
@@ -180,19 +176,12 @@ export async function resolveCacheStorageEnv() {
|
|
|
180
176
|
return false;
|
|
181
177
|
}
|
|
182
178
|
try {
|
|
183
|
-
const resolved = await
|
|
184
|
-
applyLakebaseToEnv(resolved);
|
|
185
|
-
// `??=` so an explicitly configured PGUSER stays authoritative. The lookup
|
|
186
|
-
// falls back to the workspace API and returns undefined rather than throwing,
|
|
187
|
-
// so a failure here just leaves the pool to find its own username.
|
|
188
|
-
const user = await getUsernameWithApiLookup({});
|
|
189
|
-
if (user)
|
|
190
|
-
process.env.PGUSER ??= user;
|
|
179
|
+
const { resolved, user } = await applyLakebaseEnv({ autoCreate: false }, AbortSignal.timeout(LAKEBASE_RESOLVE_TIMEOUT_MS));
|
|
191
180
|
logger.info("lakebase resolved for the gate cache", {
|
|
192
181
|
host: resolved.host,
|
|
193
182
|
database: resolved.database,
|
|
194
183
|
endpoint: resolved.endpoint,
|
|
195
|
-
user
|
|
184
|
+
user,
|
|
196
185
|
});
|
|
197
186
|
return true;
|
|
198
187
|
}
|
|
@@ -239,7 +228,8 @@ export async function startGateApp(config) {
|
|
|
239
228
|
// `handle.authGate` is the in-process gate API the proxy drives.
|
|
240
229
|
//
|
|
241
230
|
// `autoConfigure: false` because {@link resolveCacheStorageEnv} above already
|
|
242
|
-
//
|
|
231
|
+
// ran the one piece of it this app wants (`applyLakebaseEnv`), on this app's
|
|
232
|
+
// terms - no auto-create, and a warning instead of a throw.
|
|
243
233
|
const handle = await createApp({
|
|
244
234
|
autoConfigure: false,
|
|
245
235
|
plugins: [
|
|
@@ -265,4 +255,4 @@ export async function startGateApp(config) {
|
|
|
265
255
|
logger.info("gate app ready (no server; proxy-driven)");
|
|
266
256
|
return handle.authGate;
|
|
267
257
|
}
|
|
268
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBRSx3QkFBd0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlELE9BQU8sRUFBRSxTQUFTLElBQUksV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDL0UsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsS0FBSyxJQUFJLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzFELE9BQU8sRUFBRSxRQUFRLEVBQStELE1BQU0sYUFBYSxDQUFDO0FBRXBHLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFFeEM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxPQUFlO0lBQ3ZDLE9BQU8sT0FBTyxJQUFJLEVBQUUsSUFBSSxPQUFPLEdBQUcsRUFBRSxLQUFLLENBQUM7UUFDeEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFBRSxRQUFRLENBQUM7UUFDMUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFLRCwrQ0FBK0M7QUFDL0MsTUFBTSxXQUFXLEdBQUcsOERBQThELENBQUM7QUFFbkY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQVksRUFBRSxJQUFjO0lBQzVELE9BQU87UUFDTCxJQUFJ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QUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7SUFDeEQsT0FBTyxNQUFNLENBQUMsUUFBdUIsQ0FBQztBQUN4QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUaGUgdHVubmVsIGdhdGUncyB0aW55IEFwcEtpdCBcImFwcFwiIC0gYGNyZWF0ZUFwcGAgV0lUSE9VVCBhIGBzZXJ2ZXIoKWAgcGx1Z2luLlxuICpcbiAqIFRoZXJlIGlzIG5vIEhUVFAgc2VydmVyIGhlcmU6IHRoZSB0dW5uZWwgcHJveHkgaXMgdGhlIHNlcnZlciwgYW5kIGl0IGNhbGxzIHRoZVxuICogZ2F0ZSBoYW5kbGVycyBpbi1wcm9jZXNzLiBgY3JlYXRlQXBwYCBpcyB1c2VkIG9ubHkgZm9yIHdoYXQgaXQgYXV0by13aXJlczpcbiAqICAgLSBgQ2FjaGVNYW5hZ2VyYCAoTGFrZWJhc2Ugd2hlbiB0aGlzIHByb2Nlc3MgY2FuIHJlYWNoIGl0LCBlbHNlIG1lbW9yeSkgLVxuICogICAgIHdoaWNoIHRoZSBPVFAgYENvZGVTdG9yZWAgYW5kIHRoZSBzZXNzaW9uIHNpZ25pbmcga2V5IHVzZSBmb3Igc3RvcmFnZSArIFRUTFxuICogICAgIGV2aWN0aW9uO1xuICogICAtIHRoZSBgZW1haWwoKWAgdHJhbnNwb3J0IChTTVRQIC8gb3V0Ym94KSwgcHJpbWVkIGZyb20gZW52LCBzbyBgc2VuZENvZGVgIGNhblxuICogICAgIGRlbGl2ZXIgdGhlIG9uZS10aW1lIGNvZGU7XG4gKiAgIC0gZGJ4LXRvb2xzIGF1dG8tY29uZmlndXJhdGlvbiArIGJyYW5kaW5nIHZpYSBgQGRieC10b29scy9hcHBraXRgLlxuICpcbiAqIEl0IHJldHVybnMgdGhlIHtAbGluayBBdXRoR2F0ZUFwaX0gdGhlIHByb3h5IGRyaXZlcy4gYHNlbmRDb2RlYCBpcyB3aXJlZCBoZXJlXG4gKiAodGhlIHBsdWdpbiBjYW4ndCByZXNvbHZlIEhPVyB0byBzZW5kIG9uIGl0cyBvd24pIHRvIHRoZSBlbWFpbCBwbHVnaW4nc1xuICogdHJhbnNwb3J0LiBBIHNpZ24taW4gY29kZSBpcyBTWVNURU0gbWFpbCAtIG5vIG9uLWJlaGFsZi1vZiB1c2VyIGFza2VkIGZvciBpdFxuICogYW5kIG5vIHJlcGx5IHRvIGl0IHJlYWNoZXMgYW55b25lIC0gc28gaXQgc2VuZHMgZnJvbSB0aGUgZW1haWwgY29uZmlnJ3NcbiAqIGRvLW5vdC1yZXBseSBhZGRyZXNzIChgbm8tcmVwbHlARU1BSUxfRE9NQUlOYCB1bmxlc3MgRU1BSUxfU1lTVEVNX0ZST00gbmFtZXNcbiAqIGFub3RoZXIpLlxuICpcbiAqIEZBSUwgRkFTVDogYSBnYXRlIHRoYXQgY2FuJ3QgZW1haWwgYSBjb2RlIGlzIHVzZWxlc3MsIHNvIGlmIGVtYWlsIGRvZXMgbm90XG4gKiByZXNvbHZlIHRvIFNNVFAgbW9kZSAocmVhbCBkZWxpdmVyeSksIHRoaXMgdGhyb3dzIC0gdW5sZXNzIGBpbnNlY3VyZWAgaXMgc2V0XG4gKiAoYC0taW5zZWN1cmVgIC8gYFRVTk5FTF9JTlNFQ1VSRT10cnVlYCksIGluIHdoaWNoIGNhc2UgdGhlIGNhbGxlciBydW5zIHRoZVxuICogdHVubmVsIE9QRU4gd2l0aCBubyBnYXRlLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBnZXRVc2VybmFtZVdpdGhBcGlMb29rdXAgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBjcmVhdGVBcHAgYXMgY3JlYXRlQXBwTnMsIGxha2ViYXNlUmVzb2x2ZXIgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGJyYW5kIGFzIG5vZGVCcmFuZCB9IGZyb20gXCJAZGJ4LXRvb2xzL2NvcmVcIjtcbmltcG9ydCB7IGJyYW5kIGFzIGVtYWlsQnJhbmQsIGVtYWlsLCBzZW5kZXIsIHRyYW5zcG9ydCB9IGZyb20gXCJAZGJ4LXRvb2xzL2VtYWlsXCI7XG5pbXBvcnQgeyBlbnYsIGxvZywgc3RyaW5nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7IGF1dGhHYXRlLCB0eXBlIEF1dGhHYXRlQXBpLCB0eXBlIEF1dGhHYXRlQ29uZmlnLCB0eXBlIFNlbmRDb2RlT3B0aW9ucyB9IGZyb20gXCIuL3BsdWdpbi50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwidHVubmVsOmFwcFwiKTtcblxuLyoqXG4gKiBBIGNvZGUgVFRMIGFzIHRoZSBwbGFpbiBwaHJhc2UgdGhlIGVtYWlsIHN0YXRlcyAoXCIxMCBtaW51dGVzXCIsIFwiNDUgc2Vjb25kc1wiKS5cbiAqXG4gKiBXaG9sZSBtaW51dGVzIHJlYWQgYXMgbWludXRlczsgYW55dGhpbmcgZWxzZSBzdGF5cyBpbiBzZWNvbmRzIHJhdGhlciB0aGFuXG4gKiByb3VuZGluZywgc28gYSA5MC1zZWNvbmQgVFRMIGlzIG5vdCBhZHZlcnRpc2VkIGFzIFwiMSBtaW51dGVcIiBhbmQgYSByZWNpcGllbnQgaXNcbiAqIG5ldmVyIHRvbGQgdGhlIGNvZGUgbGl2ZXMgbG9uZ2VyIHRoYW4gaXQgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV4cGlyZXNJbihzZWNvbmRzOiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gc2Vjb25kcyA+PSA2MCAmJiBzZWNvbmRzICUgNjAgPT09IDBcbiAgICA/IHN0cmluZy5wbHVyYWxpemUoc2Vjb25kcyAvIDYwLCBcIm1pbnV0ZVwiKVxuICAgIDogc3RyaW5nLnBsdXJhbGl6ZShzZWNvbmRzLCBcInNlY29uZFwiKTtcbn1cblxuLyoqIFRoZSBwYXJ0cyBvZiB7QGxpbmsgU2VuZENvZGVPcHRpb25zfSB0aGUgY29kZSBlbWFpbCdzIGNvcHkgaXMgYnVpbHQgZnJvbS4gKi9cbnR5cGUgQ29kZUNvcHkgPSBQaWNrPFNlbmRDb2RlT3B0aW9ucywgXCJtZXNzYWdlXCIgfCBcImNvZGVUdGxTZWNvbmRzXCI+O1xuXG4vKiogVGhlIHJlYXNzdXJhbmNlIGxpbmUgY2xvc2luZyBib3RoIHBhcnRzLiAqL1xuY29uc3QgSUdOT1JFX0xJTkUgPSBcIklmIHlvdSBkaWQgbm90IHJlcXVlc3QgdGhpcyBjb2RlLCB5b3UgY2FuIGlnbm9yZSB0aGlzIGVtYWlsLlwiO1xuXG4vKipcbiAqIFRoZSBIVE1MIHBhcnQncyBzb3VyY2U6IHRoZSBmdWxsIGJyYW5kZWQgdGVtcGxhdGUsIHdpdGggdGhlIGNvZGUgYXMgYSBsYXJnZVxuICogc3R5bGVkIGhlYWRpbmcgKGAjIyBgIGlzIHdoYXQgbWFrZXMgaXQgcHJvbWluZW50IGluIGFuIGluYm94KS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGVFbWFpbEh0bWxCb2R5KGNvZGU6IHN0cmluZywgb3B0czogQ29kZUNvcHkpOiBzdHJpbmcge1xuICByZXR1cm4gW1xuICAgIG9wdHMubWVzc2FnZSxcbiAgICBcIlwiLFxuICAgIGAjIyAke2NvZGV9YCxcbiAgICBcIlwiLFxuICAgIGBUaGlzIGNvZGUgZXhwaXJlcyBpbiAke2V4cGlyZXNJbihvcHRzLmNvZGVUdGxTZWNvbmRzKX0uYCxcbiAgICBcIlwiLFxuICAgIElHTk9SRV9MSU5FLFxuICBdLmpvaW4oXCJcXG5cIik7XG59XG5cbi8qKlxuICogVGhlIGB0ZXh0L3BsYWluYCBwYXJ0LCBzdXBwbGllZCBFWFBMSUNJVExZIHJhdGhlciB0aGFuIHJlbmRlcmVkIGZyb20gdGhlIHRyZWVcbiAqIGFib3ZlLiBCb3RoIHBhcnRzIHNheSB0aGUgc2FtZSB0aGluZzsgb25seSB0aGUgbGluZSBsYXlvdXQgZGlmZmVycy5cbiAqXG4gKiBUaGUgcHJvbXB0IGFuZCB0aGUgY29kZSBzaGFyZSBPTkUgbGluZSAoXCJZb3VyIHZlcmlmaWNhdGlvbiBjb2RlIGlzOiAxMjM0NTZcIikuXG4gKiBUaGF0IHNpbmdsZS1saW5lIHNoYXBlIGlzIHdoYXQgaU9TLCBHbWFpbCwgT3V0bG9vaywgYW5kIEFuZHJvaWQgY29kZSBkZXRlY3Rpb25cbiAqIGtleXMgb24gbW9zdCByZWxpYWJseSAtIHRoZSBoZXVyaXN0aWNzIGxvb2sgZm9yIGEgY29kZSBpbiB0aGUgc2FtZSBzZW50ZW5jZSBhc1xuICogYSByZWNvZ25pemVkIHByb21wdCwgc28gc3BsaXR0aW5nIHRoZW0gYWNyb3NzIGxpbmVzIG1ha2VzIGRldGVjdGlvbiBkZXBlbmRlbnRcbiAqIG9uIHRoZSBjbGllbnQsIGFuZCBhbnkgYmxhbmsgbGluZSBiZXR3ZWVuIHRoZW0gZGVmZWF0cyBpdCBvdXRyaWdodC5cbiAqXG4gKiBUaGUgR0VORVJBVEVEIHRleHQgcGFydCBjYW5ub3QgaG9sZCB0aGF0IHNoYXBlIGF0IGFsbDogaXQgaXMgYSByZW5kZXJpbmcgb2YgdGhlXG4gKiBIVE1MLCBzbyBpdCBjYXJyaWVzIHRoZSBicmFuZCBoZWFkZXIvZm9vdGVyIGFuZCB0dXJucyB0aGUgY29kZSBoZWFkaW5nJ3MgQ1NTXG4gKiBtYXJnaW4gaW50byBibGFuayBsaW5lcywgYXJyaXZpbmcgYXMgYHByb21wdFxcblxcblxcbmNvZGVgLlxuICpcbiAqIFRoZSBjb2RlIGlzIHZpc2libGUgdGV4dCBpbiBCT1RIIHBhcnRzLCBuZXZlciBhbiBpbWFnZSwgc28gYSBjbGllbnQgc2NyYXBpbmdcbiAqIGVpdGhlciBvbmUgZmluZHMgaXQuIE5vIHRyYWlsZXIgbGluZSBmb2xsb3dzIHRoZSBjb3B5IC0gQXBwbGUncyBkb21haW4tYm91bmRcbiAqIGBAZG9tYWluICNjb2RlYCBmb290ZXIgaXMgZGVsaWJlcmF0ZWx5IE5PVCBlbWl0dGVkLCBzaW5jZSBpdCBjb25zdHJhaW5zIHRoZVxuICogY29kZSB0byBvbmUgb3JpZ2luIGFuZCBpcyBub3Qgd2hhdCB0aGUgYnJvYWRseS1jb21wYXRpYmxlIHNoYXBlIG5lZWRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29kZUVtYWlsVGV4dEJvZHkoY29kZTogc3RyaW5nLCBvcHRzOiBDb2RlQ29weSk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgYCR7b3B0cy5tZXNzYWdlfSAke2NvZGV9YCxcbiAgICBgVGhpcyBjb2RlIGV4cGlyZXMgaW4gJHtleHBpcmVzSW4ob3B0cy5jb2RlVHRsU2Vjb25kcyl9LmAsXG4gICAgXCJcIixcbiAgICBJR05PUkVfTElORSxcbiAgXS5qb2luKFwiXFxuXCIpO1xufVxuXG4vKipcbiAqIFRoZSBTVUJKRUNUIGxpbmUsIHdpdGggdGhlIGNvZGUgaW4gaXQ6IGBcIjEyMzQ1NiBpcyB5b3VyIHZlcmlmaWNhdGlvbiBjb2RlXCJgLlxuICpcbiAqIFRoZSBjb2RlIGhhcyB0byBiZSBoZXJlLCBub3Qgb25seSBpbiB0aGUgYm9keSwgYmVjYXVzZSBvZiB3aGF0IG1vYmlsZSBhdXRvZmlsbFxuICogYWN0dWFsbHkgcmVhZHMuIGlPUyBvZmZlcnMgYSBjb2RlIGZyb20gYW4gaW5jb21pbmcgTk9USUZJQ0FUSU9OIC0gbmF0aXZlbHkgZm9yXG4gKiBNZXNzYWdlcyBhbmQgTWFpbCwgYW5kIHNpbmNlIGlPUyAyNiBmb3IgYW55IGFwcCdzIG5vdGlmaWNhdGlvbiB0ZXh0LCB3aGljaCBpc1xuICogd2hhdCBmaW5hbGx5IG1hZGUgR21haWwgd29yayAtIGFuZCBhIG5vdGlmaWNhdGlvbiBjb250YWlucyB0aGUgc2VuZGVyLCB0aGVcbiAqIHN1YmplY3QsIGFuZCBhIHNob3J0IHNuaXBwZXQuIE5vdGhpbmcgZWxzZS4gQSBjb2RlIHRoYXQgbGl2ZXMgaW4gdGhlIGJvZHkgaXNcbiAqIGludmlzaWJsZSB0byBpdCwgaG93ZXZlciBjbGVhbmx5IHRoZSBib2R5IGlzIGZvcm1hdHRlZCwgd2hpY2ggaXMgd2h5IGEgcGVyZmVjdGx5XG4gKiBzaGFwZWQgYHRleHQvcGxhaW5gIHBhcnQgc3RpbGwgcHJvZHVjZWQgbm8gYXV0b2ZpbGwgcHJvbXB0IGluIEdtYWlsLlxuICpcbiAqIGA8Y29kZT4gaXMgeW91ciA8dGhpbmc+YCByYXRoZXIgdGhhbiBgPHRoaW5nPjogPGNvZGU+YCBiZWNhdXNlIHRoZSBsZWFkaW5nIGNvZGVcbiAqIHN1cnZpdmVzIFRSVU5DQVRJT046IGEgbm90aWZpY2F0aW9uIGFuZCBhbiBpbmJveCBsaXN0IGJvdGggY3V0IHRoZSBzdWJqZWN0LCBhbmRcbiAqIHRoZSBwbGF0Zm9ybSBoZXVyaXN0aWNzIHdhbnQgdGhlIGNvZGUgaW4gdGhlIHNhbWUgc2VudGVuY2UgYXMgYSByZWNvZ25pemVkXG4gKiBwcm9tcHQgKFwiY29kZVwiLCBcInZlcmlmaWNhdGlvblwiKS4gUHV0dGluZyBpdCBmaXJzdCBrZWVwcyBib3RoIGludGFjdCBubyBtYXR0ZXJcbiAqIHdoZXJlIHRoZSBjdXQgbGFuZHMuXG4gKlxuICogYHN1YmplY3RgIGlzIHRoZSBjb25maWd1cmVkIGxpbmUgKFwiWW91ciB2ZXJpZmljYXRpb24gY29kZVwiKSwgbG93ZXItY2FzZWQgYXQgaXRzXG4gKiBmaXJzdCB3b3JkIHNvIHRoZSBzZW50ZW5jZSByZWFkcyBuYXR1cmFsbHksIGFuZCBsZWZ0IEFMT05FIHdoZW4gaXQgZG9lcyBub3QgbG9va1xuICogbGlrZSB0aGUgY29udmVudGlvbmFsIHBocmFzaW5nIC0gYW4gb3BlcmF0b3Igd2hvIHNldCBhIGRlbGliZXJhdGUgc3ViamVjdCBnZXRzXG4gKiB0aGVpcnMgd2l0aCB0aGUgY29kZSBwcmVmaXhlZCwgbm90IGEgbWFuZ2xlZCBoeWJyaWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2RlRW1haWxTdWJqZWN0KGNvZGU6IHN0cmluZywgc3ViamVjdDogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgdHJpbW1lZCA9IHN1YmplY3QudHJpbSgpO1xuICBjb25zdCBjb252ZW50aW9uYWwgPSAvXnlvdXJcXHMrL2kuZXhlYyh0cmltbWVkKTtcbiAgY29uc3QgcmVzdCA9IGNvbnZlbnRpb25hbCA/IHRyaW1tZWQuc2xpY2UoY29udmVudGlvbmFsWzBdLmxlbmd0aCkgOiB0cmltbWVkO1xuICByZXR1cm4gY29udmVudGlvbmFsID8gYCR7Y29kZX0gaXMgeW91ciAke3Jlc3R9YCA6IGAke2NvZGV9IC0gJHt0cmltbWVkfWA7XG59XG5cbi8qKlxuICogVGhlIFBSRUhFQURFUjogdGhlIHNuaXBwZXQgYmVzaWRlIHRoZSBzdWJqZWN0IGluIGFuIGluYm94IGxpc3QsIGFuZCB0aGUgYm9keSBvZlxuICogdGhlIHB1c2ggbm90aWZpY2F0aW9uLiBDYXJyaWVzIHRoZSBjb2RlIGZvciB0aGUgc2FtZSByZWFzb24gdGhlIHN1YmplY3QgZG9lcyAtXG4gKiBpdCBpcyB0aGUgb3RoZXIgaGFsZiBvZiB3aGF0IGEgbm90aWZpY2F0aW9uIHNob3dzIC0gYW5kIHJlcGVhdHMgdGhlIHByb21wdFxuICogd29yZGluZyBzbyBhIGhldXJpc3RpYyBzY2FubmluZyB0aGUgc25pcHBldCBhbG9uZSBmaW5kcyBhIGNvZGUgbmV4dCB0byBhIHBocmFzZVxuICogaXQgcmVjb2duaXplcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGVFbWFpbFByZXZpZXcoY29kZTogc3RyaW5nLCBvcHRzOiBDb2RlQ29weSk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtvcHRzLm1lc3NhZ2V9ICR7Y29kZX1gO1xufVxuXG5jb25zdCB7IGNyZWF0ZUFwcCB9ID0gY3JlYXRlQXBwTnM7XG5jb25zdCB7IGFwcGx5TGFrZWJhc2VUb0VudiwgcmVzb2x2ZUxha2ViYXNlQ29ubmVjdGlvbiB9ID0gbGFrZWJhc2VSZXNvbHZlcjtcbmNvbnN0IHsgcmVzb2x2ZVN5c3RlbVNlbmRlckFkZHJlc3MgfSA9IHNlbmRlcjtcbmNvbnN0IHsgZ2V0RW1haWxSdW50aW1lLCBzZW5kRW1haWwgfSA9IHRyYW5zcG9ydDtcbmNvbnN0IHsgZW1haWxCcmFuZEZyb21Db250ZXh0IH0gPSBlbWFpbEJyYW5kO1xuY29uc3QgeyBsb2FkQnJhbmRDb250ZXh0IH0gPSBub2RlQnJhbmQ7XG5cbi8qKlxuICogRW52IHZhcnMgd2hvc2UgcHJlc2VuY2UgbWVhbnMgYSBMYWtlYmFzZSBkYXRhYmFzZSB3YXMgYm91bmQgdG8gdGhpcyBkZXBsb3ltZW50LlxuICogYExBS0VCQVNFX0VORFBPSU5UYCBpcyB3aGF0IGEgRGF0YWJyaWNrcyBBcHAgYHBvc3RncmVzYCByZXNvdXJjZSBiaW5kaW5nIHNldHM7XG4gKiBgUEdIT1NUYCBpcyB0aGUgbG9jYWwvbWFudWFsIHNwZWxsaW5nLlxuICovXG5jb25zdCBMQUtFQkFTRV9FTlYgPSBbXCJMQUtFQkFTRV9FTkRQT0lOVFwiLCBcIlBHSE9TVFwiXSBhcyBjb25zdDtcblxuLyoqXG4gKiBVcHBlciBib3VuZCBvbiByZXNvbHZpbmcgdGhlIExha2ViYXNlIGNvbm5lY3Rpb24uIFRoZSBnYXRlIGlzIGluIHRoZSByZXF1ZXN0XG4gKiBwYXRoIGZvciBldmVyeSB2aXNpdG9yLCBzbyBhIHNsb3cgd29ya3NwYWNlIEFQSSBtdXN0IG5vdCBob2xkIHVwIGJvb3RcbiAqIGluZGVmaW5pdGVseTsgYSBtZW1vcnkgY2FjaGUgaXMgYSBkZWdyYWRlZCBnYXRlLCBhbiB1bmJvb3RlZCBvbmUgaXMgbm8gZ2F0ZS5cbiAqL1xuY29uc3QgTEFLRUJBU0VfUkVTT0xWRV9USU1FT1VUX01TID0gNjBfMDAwO1xuXG4vKipcbiAqIEZpbGwgaW4gdGhlIExha2ViYXNlIGNvbm5lY3Rpb24gZW52IEFwcEtpdCdzIGNhY2hlIG5lZWRzLCBzbyBgQ2FjaGVNYW5hZ2VyYFxuICogY2hvb3NlcyBQRVJTSVNURU5UIHN0b3JhZ2UgaW5zdGVhZCBvZiBtZW1vcnkuXG4gKlxuICogVGhpcyBpcyB3aGF0IG1ha2VzIHRoZSBnYXRlJ3Mgc2Vzc2lvbiBzaWduaW5nIGtleSBhbmQgb3V0c3RhbmRpbmcgb25lLXRpbWVcbiAqIGNvZGVzIHN1cnZpdmUgYSByZXN0YXJ0LCBhbmQgaXQgaGFzIHRvIGJlIGRvbmUgZXhwbGljaXRseSBoZXJlLiBBcHBLaXQgcGlja3NcbiAqIExha2ViYXNlIGZvciB0aGUgY2FjaGUgb25seSB3aGVuIGBjcmVhdGVMYWtlYmFzZVBvb2woKWAgc3VjY2VlZHMsIGFuZCB0aGF0IHBvb2xcbiAqIHJlYWRzIEZPVVIgdGhpbmdzIG9mZiBgcHJvY2Vzcy5lbnZgOiBgTEFLRUJBU0VfRU5EUE9JTlRgLCBgUEdIT1NUYCxcbiAqIGBQR0RBVEFCQVNFYCwgYW5kIGEgdXNlcm5hbWUgKGBQR1VTRVJgLCBvciBgREFUQUJSSUNLU19DTElFTlRfSURgIGZvciBhIHNlcnZpY2VcbiAqIHByaW5jaXBhbCkuIEEgRGF0YWJyaWNrcyBBcHAgYHBvc3RncmVzYCByZXNvdXJjZSBiaW5kaW5nIHN1cHBsaWVzIG9ubHlcbiAqIGBMQUtFQkFTRV9FTkRQT0lOVGAuIFRoZSByZXNvbHZlciB0dXJucyB0aGF0IG9uZSB2YWx1ZSBpbnRvIHRoZSBob3N0IGFuZFxuICogZGF0YWJhc2U7IHRoZSB1c2VybmFtZSBpcyBsb29rZWQgdXAgc2VwYXJhdGVseSwgYmVjYXVzZSBtaXNzaW5nIGl0IGZhaWxzIHBvb2xcbiAqIGNvbnN0cnVjdGlvbiBqdXN0IGFzIGhhcmQgYXMgYSBtaXNzaW5nIGhvc3QgLSBhbmQgaXQgaXMgd2hhdCBhIExPQ0FMIHJ1biAoYVxuICogZGV2ZWxvcGVyIG9uIGEgUEFULCB3aXRoIG5vIGBEQVRBQlJJQ0tTX0NMSUVOVF9JRGApIGlzIGFsd2F5cyBtaXNzaW5nLiBXaXRob3V0XG4gKiBhbGwgZm91ciB0aGUgcG9vbCBjYW5ub3QgYmUgYnVpbHQsIHRoZSBjYWNoZSBzaWxlbnRseSBkZWdyYWRlcyB0byBpbi1tZW1vcnksIGFuZFxuICogZXZlcnkgcmVkZXBsb3kgc2lnbnMgb3V0IGV2ZXJ5IHVzZXIgKHRoZSBleGFjdCBzeW1wdG9tIHRoaXMgZXhpc3RzIHRvIHByZXZlbnQpLlxuICpcbiAqIGBAZGJ4LXRvb2xzL2FwcGtpdGAncyBgY3JlYXRlQXBwYCB3b3VsZCBub3JtYWxseSBkbyB0aGlzIHZpYSBgYXV0b0NvbmZpZ3VyZWAsXG4gKiBidXQgaXQgZ2F0ZXMgdGhhdCBvbiBhIGBsYWtlYmFzZSgpYCBwbHVnaW4gYmVpbmcgcmVnaXN0ZXJlZCAtIGFuZCB0aGlzIGFwcFxuICogcmVnaXN0ZXJzIG5vbmUsIGJlY2F1c2UgaXQgaGFzIG5vIHNlcnZlciB0byBtb3VudCBMYWtlYmFzZSByb3V0ZXMgb24uIENhbGxpbmdcbiAqIHRoZSByZXNvbHZlciBkaXJlY3RseSBhbHNvIGxldHMgdGhlIGdhdGUgYmUgc3RyaWN0ZXIgdGhhbiBgYXV0b0NvbmZpZ3VyZWAgaXM6XG4gKlxuICogICAtIEl0IHJ1bnMgT05MWSB3aGVuIGEgTGFrZWJhc2UgZW52IHZhciBpcyBwcmVzZW50LiBBIHR1bm5lbCBpcyBhIHdyYXBwZXJcbiAqICAgICBhcm91bmQgc29tZW9uZSBlbHNlJ3MgYXBwIGFuZCBtdXN0IG5vdCBpbnZlbnQgaW5mcmFzdHJ1Y3R1cmUsIHNvIHdpdGhcbiAqICAgICBub3RoaW5nIGJvdW5kIGl0IHNraXBzIHJhdGhlciB0aGFuIGZhbGxpbmcgdGhyb3VnaCB0aGUgcmVzb2x2ZXInc1xuICogICAgIGxpc3Qtb3ItQ1JFQVRFLWEtcHJvamVjdCBwYXRoLlxuICogICAtIGBhdXRvQ3JlYXRlOiBmYWxzZWAgZm9yIHRoZSBzYW1lIHJlYXNvbiwgaW4gY2FzZSBhIHByb2plY3QgaGFwcGVucyB0byBleGlzdC5cbiAqICAgLSBFdmVyeSBmYWlsdXJlIGlzIGEgV0FSTklORywgbmV2ZXIgYSB0aHJvdy4gVGhlIGNhY2hlIGlzIGFuIG9wdGltaXphdGlvbiBmb3JcbiAqICAgICBzZXNzaW9uIGR1cmFiaWxpdHk7IGFkbWlzc2lvbiBzdGlsbCByZXF1aXJlcyBhIGNvZGUgZGVsaXZlcmVkIHRvIGFuXG4gKiAgICAgYWxsb3ctbGlzdGVkIGFkZHJlc3MsIHNvIGEgZ2F0ZSB3aXRoIGEgbWVtb3J5IGNhY2hlIGlzIHNhZmUsIGp1c3QgZm9yZ2V0ZnVsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUNhY2hlU3RvcmFnZUVudigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKCFlbnYudGV4dChMQUtFQkFTRV9FTlYpKSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgbm8gJHtlbnYubmFtZShMQUtFQkFTRV9FTlYpfSAtIHRoZSBnYXRlIGNhY2hlIHN0YXlzIGluIG1lbW9yeTsgc2Vzc2lvbnMgYW5kIGNvZGVzIHdpbGwgbm90IHN1cnZpdmUgYSByZXN0YXJ0YCxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgcmVzb2x2ZUxha2ViYXNlQ29ubmVjdGlvbihcbiAgICAgIHsgYXV0b0NyZWF0ZTogZmFsc2UgfSxcbiAgICAgIEFib3J0U2lnbmFsLnRpbWVvdXQoTEFLRUJBU0VfUkVTT0xWRV9USU1FT1VUX01TKSxcbiAgICApO1xuICAgIGFwcGx5TGFrZWJhc2VUb0VudihyZXNvbHZlZCk7XG4gICAgLy8gYD8/PWAgc28gYW4gZXhwbGljaXRseSBjb25maWd1cmVkIFBHVVNFUiBzdGF5cyBhdXRob3JpdGF0aXZlLiBUaGUgbG9va3VwXG4gICAgLy8gZmFsbHMgYmFjayB0byB0aGUgd29ya3NwYWNlIEFQSSBhbmQgcmV0dXJucyB1bmRlZmluZWQgcmF0aGVyIHRoYW4gdGhyb3dpbmcsXG4gICAgLy8gc28gYSBmYWlsdXJlIGhlcmUganVzdCBsZWF2ZXMgdGhlIHBvb2wgdG8gZmluZCBpdHMgb3duIHVzZXJuYW1lLlxuICAgIGNvbnN0IHVzZXIgPSBhd2FpdCBnZXRVc2VybmFtZVdpdGhBcGlMb29rdXAoe30pO1xuICAgIGlmICh1c2VyKSBwcm9jZXNzLmVudi5QR1VTRVIgPz89IHVzZXI7XG4gICAgbG9nZ2VyLmluZm8oXCJsYWtlYmFzZSByZXNvbHZlZCBmb3IgdGhlIGdhdGUgY2FjaGVcIiwge1xuICAgICAgaG9zdDogcmVzb2x2ZWQuaG9zdCxcbiAgICAgIGRhdGFiYXNlOiByZXNvbHZlZC5kYXRhYmFzZSxcbiAgICAgIGVuZHBvaW50OiByZXNvbHZlZC5lbmRwb2ludCxcbiAgICAgIHVzZXI6IHByb2Nlc3MuZW52LlBHVVNFUixcbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgIFwiY291bGQgbm90IHJlc29sdmUgbGFrZWJhc2UgLSB0aGUgZ2F0ZSBjYWNoZSBzdGF5cyBpbiBtZW1vcnk7IHNlc3Npb25zIGFuZCBjb2RlcyB3aWxsIG5vdCBzdXJ2aXZlIGEgcmVzdGFydFwiLFxuICAgICAgeyBlcnJvciB9LFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQm9vdCB0aGUgZ2F0ZSBhcHAgYW5kIHJldHVybiB0aGUgQVBJIHRoZSBwcm94eSBjYWxscy4gVGhyb3dzIHdoZW4gZW1haWwgaXMgbm90XG4gKiBpbiBTTVRQIG1vZGUgKG5vIHdheSB0byBkZWxpdmVyIGEgY29kZSkgc28gYSBtaXNjb25maWd1cmVkIGdhdGUgZmFpbHMgZmFzdCBhdFxuICogc3RhcnR1cCByYXRoZXIgdGhhbiBzaWxlbnRseSBhY2NlcHRpbmcgbm9ib2R5OyB0aGUgY2FsbGVyIG1heSBjYXRjaCB0aGlzIGFuZFxuICogZmFsbCBiYWNrIHRvIGluc2VjdXJlL29wZW4gbW9kZSB3aGVuIHRoZSBvcGVyYXRvciBvcHRlZCBpbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0R2F0ZUFwcChjb25maWc6IEF1dGhHYXRlQ29uZmlnKTogUHJvbWlzZTxBdXRoR2F0ZUFwaT4ge1xuICAvLyBUaGUgaG9zdCBhcHAncyBvd24gYnJhbmQgKGBicmFuZGluZy9icmFuZC55YW1sYCBkaXNjb3ZlcmVkIGZyb20gY3dkKSBvciB0aGVcbiAgLy8gZGJ4LXRvb2xzIGRlZmF1bHQuIFRoaXMgaXMgdGhlIE9ORSBicmFuZCBzb3VyY2UgZm9yIHRoZSBnYXRlOiBpdCBzdHlsZXMgdGhlXG4gIC8vIGNvZGUgZW1haWwgKGFjY2VudCBiYW5kLCBmb250LCBsb2dvKSB2aWEgdGhlIGVtYWlsIHBsdWdpbiBBTkQgc3VwcGxpZXMgdGhlXG4gIC8vIGRpc3BsYXkgbmFtZSB0aGUgY29weSB1c2VzLCBzbyBhIGRlcGxveW1lbnQgdGhhdCB0aGVtZXMgaXRzIGFwcCB0aGVtZXMgaXRzXG4gIC8vIHNpZ24taW4gZW1haWwgd2l0aCBpdC4gQW4gZXhwbGljaXQgYGJyYW5kTmFtZWAgc3RpbGwgd2lucyAoc2VlIGJlbG93KS5cbiAgY29uc3QgY29udGV4dCA9IGF3YWl0IGxvYWRCcmFuZENvbnRleHQoKTtcblxuICAvLyBCZWZvcmUgYGNyZWF0ZUFwcGAsIGJlY2F1c2UgQXBwS2l0IHJlc29sdmVzIHRoZSBjYWNoZSdzIHN0b3JhZ2UgZHVyaW5nIGl0IGFuZFxuICAvLyByZWFkcyB0aGUgY29ubmVjdGlvbiBvdXQgb2YgYHByb2Nlc3MuZW52YCB3aGVuIGl0IGRvZXMuIFNlZSB0aGUgZnVuY3Rpb24nc1xuICAvLyBkb2NzIGZvciB3aHkgdGhlIGdhdGUgcmVzb2x2ZXMgdGhpcyBpdHNlbGYuXG4gIGF3YWl0IHJlc29sdmVDYWNoZVN0b3JhZ2VFbnYoKTtcblxuICAvLyBgc2VuZENvZGVgIGRlbGl2ZXJzIHRoZSBPVFAgdGhyb3VnaCB0aGUgZW1haWwgcGx1Z2luJ3MgU0hBUkVEIHRyYW5zcG9ydCwgd2hpY2hcbiAgLy8gdGhlIGBlbWFpbCgpYCBwbHVnaW4gcHJpbWVzIGR1cmluZyBpdHMgYHNldHVwKClgIChhd2FpdGVkIGJ5IGBjcmVhdGVBcHBgXG4gIC8vIGJlbG93KS4gVXNpbmcgdGhlIG1vZHVsZS1sZXZlbCBgc2VuZEVtYWlsYCBhdm9pZHMgYSBjaXJjdWxhciBkZXBlbmRlbmN5IG9uIHRoZVxuICAvLyBhcHAgaGFuZGxlJ3MgaW5mZXJyZWQgdHlwZS4gVGhlIGBGcm9tYCBpcyB0aGUgU1lTVEVNIHNlbmRlcjogYSB2ZXJpZmljYXRpb25cbiAgLy8gY29kZSBpcyBtYWNoaW5lLWdlbmVyYXRlZCBhbmQgdW5hbnN3ZXJhYmxlLCBzbyBpdCBtdXN0IG5vdCBhcnJpdmUgZnJvbSBhXG4gIC8vIHBlcnNvbidzIGFkZHJlc3MgaW52aXRpbmcgYSByZXBseS5cbiAgY29uc3Qgc2VuZENvZGU6IE5vbk51bGxhYmxlPEF1dGhHYXRlQ29uZmlnW1wic2VuZENvZGVcIl0+ID0gYXN5bmMgKHRvLCBjb2RlLCBvcHRzKSA9PiB7XG4gICAgY29uc3QgZnJvbSA9IHJlc29sdmVTeXN0ZW1TZW5kZXJBZGRyZXNzKGdldEVtYWlsUnVudGltZSgpLmNvbmZpZyk7XG4gICAgYXdhaXQgc2VuZEVtYWlsKFxuICAgICAge1xuICAgICAgICB0bzogW3RvXSxcbiAgICAgICAgLy8gVGhlIGNvZGUgcmlkZXMgaW4gdGhlIFNVQkpFQ1QgYW5kIHRoZSBwcmVoZWFkZXIsIG5vdCBqdXN0IHRoZSBib2R5OlxuICAgICAgICAvLyB0aG9zZSB0d28gc3RyaW5ncyBhcmUgdGhlIHdob2xlIG9mIGEgcHVzaCBub3RpZmljYXRpb24sIGFuZCBhXG4gICAgICAgIC8vIG5vdGlmaWNhdGlvbiBpcyB3aGF0IG1vYmlsZSBhdXRvZmlsbCByZWFkcy4gU2VlIGBjb2RlRW1haWxTdWJqZWN0YC5cbiAgICAgICAgc3ViamVjdDogY29kZUVtYWlsU3ViamVjdChjb2RlLCBvcHRzLnN1YmplY3QpLFxuICAgICAgICBib2R5OiBjb2RlRW1haWxIdG1sQm9keShjb2RlLCBvcHRzKSxcbiAgICAgIH0sXG4gICAgICBmcm9tLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgeyB0ZXh0OiBjb2RlRW1haWxUZXh0Qm9keShjb2RlLCBvcHRzKSwgcHJldmlldzogY29kZUVtYWlsUHJldmlldyhjb2RlLCBvcHRzKSB9LFxuICAgICk7XG4gIH07XG5cbiAgLy8gYGNyZWF0ZUFwcGAgbmFtZXNwYWNlcyBlYWNoIHBsdWdpbidzIGV4cG9ydHMgb24gdGhlIGhhbmRsZSBieSBtYW5pZmVzdCBuYW1lO1xuICAvLyBgaGFuZGxlLmF1dGhHYXRlYCBpcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSSB0aGUgcHJveHkgZHJpdmVzLlxuICAvL1xuICAvLyBgYXV0b0NvbmZpZ3VyZTogZmFsc2VgIGJlY2F1c2Uge0BsaW5rIHJlc29sdmVDYWNoZVN0b3JhZ2VFbnZ9IGFib3ZlIGFscmVhZHlcbiAgLy8gZGlkIHRoZSBvbmUgcGllY2Ugb2YgaXQgdGhpcyBhcHAgd2FudHMsIG9uIHRoaXMgYXBwJ3MgdGVybXMuXG4gIGNvbnN0IGhhbmRsZSA9IGF3YWl0IGNyZWF0ZUFwcCh7XG4gICAgYXV0b0NvbmZpZ3VyZTogZmFsc2UsXG4gICAgcGx1Z2luczogW1xuICAgICAgLy8gQnJhbmQgdGhlIGNvZGUgZW1haWwgZnJvbSB0aGUgcmVzb2x2ZWQgY29udGV4dCwgdGhlIHNhbWUgYnJpZGdlIGV2ZXJ5XG4gICAgICAvLyBvdGhlciBkYngtdG9vbHMgZW1haWwgc3VyZmFjZSB1c2VzIChhY2NlbnQgKyBmb250IGlubGluZWQsIGxvZ28gb25seSB3aGVuXG4gICAgICAvLyBpdCBpcyBhIGZldGNoYWJsZSBVUkwgLSBhIHBhY2thZ2UtZXhwb3J0IHBhdGggY2Fubm90IGxvYWQgaW4gYW4gaW5ib3gpLlxuICAgICAgZW1haWwoeyBicmFuZDogZW1haWxCcmFuZEZyb21Db250ZXh0KGNvbnRleHQpIH0pLFxuICAgICAgLy8gYGJyYW5kTmFtZWAgZmFsbHMgYmFjayB0byB0aGUgcmVzb2x2ZWQgY29udGV4dCdzIGRpc3BsYXkgbmFtZSwgc28gdGhlXG4gICAgICAvLyBlbWFpbCBjb3B5IG5hbWVzIHRoZSBhcHAgcmF0aGVyIHRoYW4gYSBnZW5lcmljIHBsYWNlaG9sZGVyLiBTcGVsbGVkIGFzIGFuXG4gICAgICAvLyBleHBsaWNpdCBgPz9gIHJhdGhlciB0aGFuIGEga2V5IGJlZm9yZSBgLi4uY29uZmlnYDogY29tbWFuZGVyIHNldHNcbiAgICAgIC8vIGBicmFuZE5hbWVgIG9uIHRoZSBvcHRpb25zIG9iamVjdCB3aGV0aGVyIG9yIG5vdCB0aGUgZmxhZyB3YXMgcGFzc2VkLCBzb1xuICAgICAgLy8gc3ByZWFkaW5nIGl0IHdvdWxkIGNsb2JiZXIgdGhlIGNvbnRleHQgbmFtZSB3aXRoIGB1bmRlZmluZWRgLlxuICAgICAgYXV0aEdhdGUoeyAuLi5jb25maWcsIGJyYW5kTmFtZTogY29uZmlnLmJyYW5kTmFtZSA/PyBjb250ZXh0Lm5hbWUsIHNlbmRDb2RlIH0pLFxuICAgIF0sXG4gIH0pO1xuXG4gIC8vIEZhaWwgZmFzdDogdGhlIGdhdGUgbmVlZHMgU01UUCB0byBlbWFpbCBjb2Rlcy4gYGdldEVtYWlsUnVudGltZSgpYCByZXNvbHZlcyB0b1xuICAvLyBgbW9kZTogXCJmaWxlXCJgIChvdXRib3gpIG9yIHRocm93cyB3aGVuIG5vIFNNVFAgY3JlZHMgYXJlIGNvbmZpZ3VyZWQgLSBuZWl0aGVyXG4gIC8vIGNhbiBkZWxpdmVyIHRvIGEgcmVhbCBpbmJveCwgc28gcmVmdXNlIHRvIGJyaW5nIHVwIGEgZ2F0ZSB0aGF0IGxldHMgbm9ib2R5IGluLlxuICBpZiAoZ2V0RW1haWxSdW50aW1lKCkuY29uZmlnLm1vZGUgIT09IFwic210cFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJlbWFpbCBpcyBub3QgY29uZmlndXJlZCBmb3IgU01UUCBkZWxpdmVyeSAtIHRoZSBPVFAgZ2F0ZSBjYW5ub3Qgc2VuZCBjb2Rlcy4gXCIgK1xuICAgICAgICBcIlNldCBTTVRQX0hPU1QvU01UUF9VU0VSL1NNVFBfUEFTU1dPUkQsIG9yIHBhc3MgLS1pbnNlY3VyZSAvIFRVTk5FTF9JTlNFQ1VSRT10cnVlIHRvIHJ1biB0aGUgdHVubmVsIG9wZW4uXCIsXG4gICAgKTtcbiAgfVxuXG4gIGxvZ2dlci5pbmZvKFwiZ2F0ZSBhcHAgcmVhZHkgKG5vIHNlcnZlcjsgcHJveHktZHJpdmVuKVwiKTtcbiAgcmV0dXJuIGhhbmRsZS5hdXRoR2F0ZSBhcyBBdXRoR2F0ZUFwaTtcbn1cbiJdfQ==
|
|
258
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXlCRztBQUVILE9BQU8sRUFBRSxTQUFTLElBQUksV0FBVyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDL0UsT0FBTyxFQUFFLEtBQUssSUFBSSxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsS0FBSyxJQUFJLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ2pGLE9BQU8sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzFELE9BQU8sRUFBRSxRQUFRLEVBQStELE1BQU0sYUFBYSxDQUFDO0FBRXBHLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7QUFFeEM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxPQUFlO0lBQ3ZDLE9BQU8sT0FBTyxJQUFJLEVBQUUsSUFBSSxPQUFPLEdBQUcsRUFBRSxLQUFLLENBQUM7UUFDeEMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxHQUFHLEVBQUUsRUFBRSxRQUFRLENBQUM7UUFDMUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQzFDLENBQUM7QUFLRCwrQ0FBK0M7QUFDL0MsTUFBTSxXQUFXLEdBQUcsOERBQThELENBQUM7QUFFbkY7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUFDLElBQVksRUFBRSxJQUFjO0lBQzVELE9BQU87UUFDTCxJQUFJLENBQUMsT0FBTztRQUNaLEVBQUU7UUFDRixNQUFNLElBQUksRUFBRTtRQUNa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RSxJQUFJLENBQUMsRUFBRSxDQUMvRSxDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBRUYsK0VBQStFO0lBQy9FLGlFQUFpRTtJQUNqRSxFQUFFO0lBQ0YsOEVBQThFO0lBQzlFLDZFQUE2RTtJQUM3RSw0REFBNEQ7SUFDNUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxTQUFTLENBQUM7UUFDN0IsYUFBYSxFQUFFLEtBQUs7UUFDcEIsT0FBTyxFQUFFO1lBQ1Asd0VBQXdFO1lBQ3hFLDRFQUE0RTtZQUM1RSwwRUFBMEU7WUFDMUUsS0FBSyxDQUFDLEVBQUUsS0FBSyxFQUFFLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDaEQsd0VBQXdFO1lBQ3hFLDRFQUE0RTtZQUM1RSxxRUFBcUU7WUFDckUsMkVBQTJFO1lBQzNFLGdFQUFnRTtZQUNoRSxRQUFRLENBQUMsRUFBRSxHQUFHLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDLFNBQVMsSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxDQUFDO1NBQy9FO0tBQ0YsQ0FBQyxDQUFDO0lBRUgsaUZBQWlGO0lBQ2pGLGdGQUFnRjtJQUNoRixpRkFBaUY7SUFDakYsSUFBSSxlQUFlLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQzdDLE1BQU0sSUFBSSxLQUFLLENBQ2IsOEVBQThFO1lBQzVFLDBHQUEwRyxDQUM3RyxDQUFDO0lBQ0osQ0FBQztJQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsMENBQTBDLENBQUMsQ0FBQztJQUN4RCxPQUFPLE1BQU0sQ0FBQyxRQUF1QixDQUFDO0FBQ3hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSB0dW5uZWwgZ2F0ZSdzIHRpbnkgQXBwS2l0IFwiYXBwXCIgLSBgY3JlYXRlQXBwYCBXSVRIT1VUIGEgYHNlcnZlcigpYCBwbHVnaW4uXG4gKlxuICogVGhlcmUgaXMgbm8gSFRUUCBzZXJ2ZXIgaGVyZTogdGhlIHR1bm5lbCBwcm94eSBpcyB0aGUgc2VydmVyLCBhbmQgaXQgY2FsbHMgdGhlXG4gKiBnYXRlIGhhbmRsZXJzIGluLXByb2Nlc3MuIGBjcmVhdGVBcHBgIGlzIHVzZWQgb25seSBmb3Igd2hhdCBpdCBhdXRvLXdpcmVzOlxuICogICAtIGBDYWNoZU1hbmFnZXJgIChMYWtlYmFzZSB3aGVuIHRoaXMgcHJvY2VzcyBjYW4gcmVhY2ggaXQsIGVsc2UgbWVtb3J5KSAtXG4gKiAgICAgd2hpY2ggdGhlIE9UUCBgQ29kZVN0b3JlYCBhbmQgdGhlIHNlc3Npb24gc2lnbmluZyBrZXkgdXNlIGZvciBzdG9yYWdlICsgVFRMXG4gKiAgICAgZXZpY3Rpb247XG4gKiAgIC0gdGhlIGBlbWFpbCgpYCB0cmFuc3BvcnQgKFNNVFAgLyBvdXRib3gpLCBwcmltZWQgZnJvbSBlbnYsIHNvIGBzZW5kQ29kZWAgY2FuXG4gKiAgICAgZGVsaXZlciB0aGUgb25lLXRpbWUgY29kZTtcbiAqICAgLSBkYngtdG9vbHMgYXV0by1jb25maWd1cmF0aW9uICsgYnJhbmRpbmcgdmlhIGBAZGJ4LXRvb2xzL2FwcGtpdGAuXG4gKlxuICogSXQgcmV0dXJucyB0aGUge0BsaW5rIEF1dGhHYXRlQXBpfSB0aGUgcHJveHkgZHJpdmVzLiBgc2VuZENvZGVgIGlzIHdpcmVkIGhlcmVcbiAqICh0aGUgcGx1Z2luIGNhbid0IHJlc29sdmUgSE9XIHRvIHNlbmQgb24gaXRzIG93bikgdG8gdGhlIGVtYWlsIHBsdWdpbidzXG4gKiB0cmFuc3BvcnQuIEEgc2lnbi1pbiBjb2RlIGlzIFNZU1RFTSBtYWlsIC0gbm8gb24tYmVoYWxmLW9mIHVzZXIgYXNrZWQgZm9yIGl0XG4gKiBhbmQgbm8gcmVwbHkgdG8gaXQgcmVhY2hlcyBhbnlvbmUgLSBzbyBpdCBzZW5kcyBmcm9tIHRoZSBlbWFpbCBjb25maWcnc1xuICogZG8tbm90LXJlcGx5IGFkZHJlc3MgKGBuby1yZXBseUBFTUFJTF9ET01BSU5gIHVubGVzcyBFTUFJTF9TWVNURU1fRlJPTSBuYW1lc1xuICogYW5vdGhlcikuXG4gKlxuICogRkFJTCBGQVNUOiBhIGdhdGUgdGhhdCBjYW4ndCBlbWFpbCBhIGNvZGUgaXMgdXNlbGVzcywgc28gaWYgZW1haWwgZG9lcyBub3RcbiAqIHJlc29sdmUgdG8gU01UUCBtb2RlIChyZWFsIGRlbGl2ZXJ5KSwgdGhpcyB0aHJvd3MgLSB1bmxlc3MgYGluc2VjdXJlYCBpcyBzZXRcbiAqIChgLS1pbnNlY3VyZWAgLyBgVFVOTkVMX0lOU0VDVVJFPXRydWVgKSwgaW4gd2hpY2ggY2FzZSB0aGUgY2FsbGVyIHJ1bnMgdGhlXG4gKiB0dW5uZWwgT1BFTiB3aXRoIG5vIGdhdGUuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUFwcCBhcyBjcmVhdGVBcHBOcywgbGFrZWJhc2VSZXNvbHZlciB9IGZyb20gXCJAZGJ4LXRvb2xzL2FwcGtpdFwiO1xuaW1wb3J0IHsgYnJhbmQgYXMgbm9kZUJyYW5kIH0gZnJvbSBcIkBkYngtdG9vbHMvY29yZVwiO1xuaW1wb3J0IHsgYnJhbmQgYXMgZW1haWxCcmFuZCwgZW1haWwsIHNlbmRlciwgdHJhbnNwb3J0IH0gZnJvbSBcIkBkYngtdG9vbHMvZW1haWxcIjtcbmltcG9ydCB7IGVudiwgbG9nLCBzdHJpbmcgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgYXV0aEdhdGUsIHR5cGUgQXV0aEdhdGVBcGksIHR5cGUgQXV0aEdhdGVDb25maWcsIHR5cGUgU2VuZENvZGVPcHRpb25zIH0gZnJvbSBcIi4vcGx1Z2luLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJ0dW5uZWw6YXBwXCIpO1xuXG4vKipcbiAqIEEgY29kZSBUVEwgYXMgdGhlIHBsYWluIHBocmFzZSB0aGUgZW1haWwgc3RhdGVzIChcIjEwIG1pbnV0ZXNcIiwgXCI0NSBzZWNvbmRzXCIpLlxuICpcbiAqIFdob2xlIG1pbnV0ZXMgcmVhZCBhcyBtaW51dGVzOyBhbnl0aGluZyBlbHNlIHN0YXlzIGluIHNlY29uZHMgcmF0aGVyIHRoYW5cbiAqIHJvdW5kaW5nLCBzbyBhIDkwLXNlY29uZCBUVEwgaXMgbm90IGFkdmVydGlzZWQgYXMgXCIxIG1pbnV0ZVwiIGFuZCBhIHJlY2lwaWVudCBpc1xuICogbmV2ZXIgdG9sZCB0aGUgY29kZSBsaXZlcyBsb25nZXIgdGhhbiBpdCBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZXhwaXJlc0luKHNlY29uZHM6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBzZWNvbmRzID49IDYwICYmIHNlY29uZHMgJSA2MCA9PT0gMFxuICAgID8gc3RyaW5nLnBsdXJhbGl6ZShzZWNvbmRzIC8gNjAsIFwibWludXRlXCIpXG4gICAgOiBzdHJpbmcucGx1cmFsaXplKHNlY29uZHMsIFwic2Vjb25kXCIpO1xufVxuXG4vKiogVGhlIHBhcnRzIG9mIHtAbGluayBTZW5kQ29kZU9wdGlvbnN9IHRoZSBjb2RlIGVtYWlsJ3MgY29weSBpcyBidWlsdCBmcm9tLiAqL1xudHlwZSBDb2RlQ29weSA9IFBpY2s8U2VuZENvZGVPcHRpb25zLCBcIm1lc3NhZ2VcIiB8IFwiY29kZVR0bFNlY29uZHNcIj47XG5cbi8qKiBUaGUgcmVhc3N1cmFuY2UgbGluZSBjbG9zaW5nIGJvdGggcGFydHMuICovXG5jb25zdCBJR05PUkVfTElORSA9IFwiSWYgeW91IGRpZCBub3QgcmVxdWVzdCB0aGlzIGNvZGUsIHlvdSBjYW4gaWdub3JlIHRoaXMgZW1haWwuXCI7XG5cbi8qKlxuICogVGhlIEhUTUwgcGFydCdzIHNvdXJjZTogdGhlIGZ1bGwgYnJhbmRlZCB0ZW1wbGF0ZSwgd2l0aCB0aGUgY29kZSBhcyBhIGxhcmdlXG4gKiBzdHlsZWQgaGVhZGluZyAoYCMjIGAgaXMgd2hhdCBtYWtlcyBpdCBwcm9taW5lbnQgaW4gYW4gaW5ib3gpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29kZUVtYWlsSHRtbEJvZHkoY29kZTogc3RyaW5nLCBvcHRzOiBDb2RlQ29weSk6IHN0cmluZyB7XG4gIHJldHVybiBbXG4gICAgb3B0cy5tZXNzYWdlLFxuICAgIFwiXCIsXG4gICAgYCMjICR7Y29kZX1gLFxuICAgIFwiXCIsXG4gICAgYFRoaXMgY29kZSBleHBpcmVzIGluICR7ZXhwaXJlc0luKG9wdHMuY29kZVR0bFNlY29uZHMpfS5gLFxuICAgIFwiXCIsXG4gICAgSUdOT1JFX0xJTkUsXG4gIF0uam9pbihcIlxcblwiKTtcbn1cblxuLyoqXG4gKiBUaGUgYHRleHQvcGxhaW5gIHBhcnQsIHN1cHBsaWVkIEVYUExJQ0lUTFkgcmF0aGVyIHRoYW4gcmVuZGVyZWQgZnJvbSB0aGUgdHJlZVxuICogYWJvdmUuIEJvdGggcGFydHMgc2F5IHRoZSBzYW1lIHRoaW5nOyBvbmx5IHRoZSBsaW5lIGxheW91dCBkaWZmZXJzLlxuICpcbiAqIFRoZSBwcm9tcHQgYW5kIHRoZSBjb2RlIHNoYXJlIE9ORSBsaW5lIChcIllvdXIgdmVyaWZpY2F0aW9uIGNvZGUgaXM6IDEyMzQ1NlwiKS5cbiAqIFRoYXQgc2luZ2xlLWxpbmUgc2hhcGUgaXMgd2hhdCBpT1MsIEdtYWlsLCBPdXRsb29rLCBhbmQgQW5kcm9pZCBjb2RlIGRldGVjdGlvblxuICoga2V5cyBvbiBtb3N0IHJlbGlhYmx5IC0gdGhlIGhldXJpc3RpY3MgbG9vayBmb3IgYSBjb2RlIGluIHRoZSBzYW1lIHNlbnRlbmNlIGFzXG4gKiBhIHJlY29nbml6ZWQgcHJvbXB0LCBzbyBzcGxpdHRpbmcgdGhlbSBhY3Jvc3MgbGluZXMgbWFrZXMgZGV0ZWN0aW9uIGRlcGVuZGVudFxuICogb24gdGhlIGNsaWVudCwgYW5kIGFueSBibGFuayBsaW5lIGJldHdlZW4gdGhlbSBkZWZlYXRzIGl0IG91dHJpZ2h0LlxuICpcbiAqIFRoZSBHRU5FUkFURUQgdGV4dCBwYXJ0IGNhbm5vdCBob2xkIHRoYXQgc2hhcGUgYXQgYWxsOiBpdCBpcyBhIHJlbmRlcmluZyBvZiB0aGVcbiAqIEhUTUwsIHNvIGl0IGNhcnJpZXMgdGhlIGJyYW5kIGhlYWRlci9mb290ZXIgYW5kIHR1cm5zIHRoZSBjb2RlIGhlYWRpbmcncyBDU1NcbiAqIG1hcmdpbiBpbnRvIGJsYW5rIGxpbmVzLCBhcnJpdmluZyBhcyBgcHJvbXB0XFxuXFxuXFxuY29kZWAuXG4gKlxuICogVGhlIGNvZGUgaXMgdmlzaWJsZSB0ZXh0IGluIEJPVEggcGFydHMsIG5ldmVyIGFuIGltYWdlLCBzbyBhIGNsaWVudCBzY3JhcGluZ1xuICogZWl0aGVyIG9uZSBmaW5kcyBpdC4gTm8gdHJhaWxlciBsaW5lIGZvbGxvd3MgdGhlIGNvcHkgLSBBcHBsZSdzIGRvbWFpbi1ib3VuZFxuICogYEBkb21haW4gI2NvZGVgIGZvb3RlciBpcyBkZWxpYmVyYXRlbHkgTk9UIGVtaXR0ZWQsIHNpbmNlIGl0IGNvbnN0cmFpbnMgdGhlXG4gKiBjb2RlIHRvIG9uZSBvcmlnaW4gYW5kIGlzIG5vdCB3aGF0IHRoZSBicm9hZGx5LWNvbXBhdGlibGUgc2hhcGUgbmVlZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb2RlRW1haWxUZXh0Qm9keShjb2RlOiBzdHJpbmcsIG9wdHM6IENvZGVDb3B5KTogc3RyaW5nIHtcbiAgcmV0dXJuIFtcbiAgICBgJHtvcHRzLm1lc3NhZ2V9ICR7Y29kZX1gLFxuICAgIGBUaGlzIGNvZGUgZXhwaXJlcyBpbiAke2V4cGlyZXNJbihvcHRzLmNvZGVUdGxTZWNvbmRzKX0uYCxcbiAgICBcIlwiLFxuICAgIElHTk9SRV9MSU5FLFxuICBdLmpvaW4oXCJcXG5cIik7XG59XG5cbi8qKlxuICogVGhlIFNVQkpFQ1QgbGluZSwgd2l0aCB0aGUgY29kZSBpbiBpdDogYFwiMTIzNDU2IGlzIHlvdXIgdmVyaWZpY2F0aW9uIGNvZGVcImAuXG4gKlxuICogVGhlIGNvZGUgaGFzIHRvIGJlIGhlcmUsIG5vdCBvbmx5IGluIHRoZSBib2R5LCBiZWNhdXNlIG9mIHdoYXQgbW9iaWxlIGF1dG9maWxsXG4gKiBhY3R1YWxseSByZWFkcy4gaU9TIG9mZmVycyBhIGNvZGUgZnJvbSBhbiBpbmNvbWluZyBOT1RJRklDQVRJT04gLSBuYXRpdmVseSBmb3JcbiAqIE1lc3NhZ2VzIGFuZCBNYWlsLCBhbmQgc2luY2UgaU9TIDI2IGZvciBhbnkgYXBwJ3Mgbm90aWZpY2F0aW9uIHRleHQsIHdoaWNoIGlzXG4gKiB3aGF0IGZpbmFsbHkgbWFkZSBHbWFpbCB3b3JrIC0gYW5kIGEgbm90aWZpY2F0aW9uIGNvbnRhaW5zIHRoZSBzZW5kZXIsIHRoZVxuICogc3ViamVjdCwgYW5kIGEgc2hvcnQgc25pcHBldC4gTm90aGluZyBlbHNlLiBBIGNvZGUgdGhhdCBsaXZlcyBpbiB0aGUgYm9keSBpc1xuICogaW52aXNpYmxlIHRvIGl0LCBob3dldmVyIGNsZWFubHkgdGhlIGJvZHkgaXMgZm9ybWF0dGVkLCB3aGljaCBpcyB3aHkgYSBwZXJmZWN0bHlcbiAqIHNoYXBlZCBgdGV4dC9wbGFpbmAgcGFydCBzdGlsbCBwcm9kdWNlZCBubyBhdXRvZmlsbCBwcm9tcHQgaW4gR21haWwuXG4gKlxuICogYDxjb2RlPiBpcyB5b3VyIDx0aGluZz5gIHJhdGhlciB0aGFuIGA8dGhpbmc+OiA8Y29kZT5gIGJlY2F1c2UgdGhlIGxlYWRpbmcgY29kZVxuICogc3Vydml2ZXMgVFJVTkNBVElPTjogYSBub3RpZmljYXRpb24gYW5kIGFuIGluYm94IGxpc3QgYm90aCBjdXQgdGhlIHN1YmplY3QsIGFuZFxuICogdGhlIHBsYXRmb3JtIGhldXJpc3RpY3Mgd2FudCB0aGUgY29kZSBpbiB0aGUgc2FtZSBzZW50ZW5jZSBhcyBhIHJlY29nbml6ZWRcbiAqIHByb21wdCAoXCJjb2RlXCIsIFwidmVyaWZpY2F0aW9uXCIpLiBQdXR0aW5nIGl0IGZpcnN0IGtlZXBzIGJvdGggaW50YWN0IG5vIG1hdHRlclxuICogd2hlcmUgdGhlIGN1dCBsYW5kcy5cbiAqXG4gKiBgc3ViamVjdGAgaXMgdGhlIGNvbmZpZ3VyZWQgbGluZSAoXCJZb3VyIHZlcmlmaWNhdGlvbiBjb2RlXCIpLCBsb3dlci1jYXNlZCBhdCBpdHNcbiAqIGZpcnN0IHdvcmQgc28gdGhlIHNlbnRlbmNlIHJlYWRzIG5hdHVyYWxseSwgYW5kIGxlZnQgQUxPTkUgd2hlbiBpdCBkb2VzIG5vdCBsb29rXG4gKiBsaWtlIHRoZSBjb252ZW50aW9uYWwgcGhyYXNpbmcgLSBhbiBvcGVyYXRvciB3aG8gc2V0IGEgZGVsaWJlcmF0ZSBzdWJqZWN0IGdldHNcbiAqIHRoZWlycyB3aXRoIHRoZSBjb2RlIHByZWZpeGVkLCBub3QgYSBtYW5nbGVkIGh5YnJpZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvZGVFbWFpbFN1YmplY3QoY29kZTogc3RyaW5nLCBzdWJqZWN0OiBzdHJpbmcpOiBzdHJpbmcge1xuICBjb25zdCB0cmltbWVkID0gc3ViamVjdC50cmltKCk7XG4gIGNvbnN0IGNvbnZlbnRpb25hbCA9IC9eeW91clxccysvaS5leGVjKHRyaW1tZWQpO1xuICBjb25zdCByZXN0ID0gY29udmVudGlvbmFsID8gdHJpbW1lZC5zbGljZShjb252ZW50aW9uYWxbMF0ubGVuZ3RoKSA6IHRyaW1tZWQ7XG4gIHJldHVybiBjb252ZW50aW9uYWwgPyBgJHtjb2RlfSBpcyB5b3VyICR7cmVzdH1gIDogYCR7Y29kZX0gLSAke3RyaW1tZWR9YDtcbn1cblxuLyoqXG4gKiBUaGUgUFJFSEVBREVSOiB0aGUgc25pcHBldCBiZXNpZGUgdGhlIHN1YmplY3QgaW4gYW4gaW5ib3ggbGlzdCwgYW5kIHRoZSBib2R5IG9mXG4gKiB0aGUgcHVzaCBub3RpZmljYXRpb24uIENhcnJpZXMgdGhlIGNvZGUgZm9yIHRoZSBzYW1lIHJlYXNvbiB0aGUgc3ViamVjdCBkb2VzIC1cbiAqIGl0IGlzIHRoZSBvdGhlciBoYWxmIG9mIHdoYXQgYSBub3RpZmljYXRpb24gc2hvd3MgLSBhbmQgcmVwZWF0cyB0aGUgcHJvbXB0XG4gKiB3b3JkaW5nIHNvIGEgaGV1cmlzdGljIHNjYW5uaW5nIHRoZSBzbmlwcGV0IGFsb25lIGZpbmRzIGEgY29kZSBuZXh0IHRvIGEgcGhyYXNlXG4gKiBpdCByZWNvZ25pemVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29kZUVtYWlsUHJldmlldyhjb2RlOiBzdHJpbmcsIG9wdHM6IENvZGVDb3B5KTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke29wdHMubWVzc2FnZX0gJHtjb2RlfWA7XG59XG5cbmNvbnN0IHsgY3JlYXRlQXBwIH0gPSBjcmVhdGVBcHBOcztcbmNvbnN0IHsgYXBwbHlMYWtlYmFzZUVudiB9ID0gbGFrZWJhc2VSZXNvbHZlcjtcbmNvbnN0IHsgcmVzb2x2ZVN5c3RlbVNlbmRlckFkZHJlc3MgfSA9IHNlbmRlcjtcbmNvbnN0IHsgZ2V0RW1haWxSdW50aW1lLCBzZW5kRW1haWwgfSA9IHRyYW5zcG9ydDtcbmNvbnN0IHsgZW1haWxCcmFuZEZyb21Db250ZXh0IH0gPSBlbWFpbEJyYW5kO1xuY29uc3QgeyBsb2FkQnJhbmRDb250ZXh0IH0gPSBub2RlQnJhbmQ7XG5cbi8qKlxuICogRW52IHZhcnMgd2hvc2UgcHJlc2VuY2UgbWVhbnMgYSBMYWtlYmFzZSBkYXRhYmFzZSB3YXMgYm91bmQgdG8gdGhpcyBkZXBsb3ltZW50LlxuICogYExBS0VCQVNFX0VORFBPSU5UYCBpcyB3aGF0IGEgRGF0YWJyaWNrcyBBcHAgYHBvc3RncmVzYCByZXNvdXJjZSBiaW5kaW5nIHNldHM7XG4gKiBgUEdIT1NUYCBpcyB0aGUgbG9jYWwvbWFudWFsIHNwZWxsaW5nLlxuICovXG5jb25zdCBMQUtFQkFTRV9FTlYgPSBbXCJMQUtFQkFTRV9FTkRQT0lOVFwiLCBcIlBHSE9TVFwiXSBhcyBjb25zdDtcblxuLyoqXG4gKiBVcHBlciBib3VuZCBvbiByZXNvbHZpbmcgdGhlIExha2ViYXNlIGNvbm5lY3Rpb24uIFRoZSBnYXRlIGlzIGluIHRoZSByZXF1ZXN0XG4gKiBwYXRoIGZvciBldmVyeSB2aXNpdG9yLCBzbyBhIHNsb3cgd29ya3NwYWNlIEFQSSBtdXN0IG5vdCBob2xkIHVwIGJvb3RcbiAqIGluZGVmaW5pdGVseTsgYSBtZW1vcnkgY2FjaGUgaXMgYSBkZWdyYWRlZCBnYXRlLCBhbiB1bmJvb3RlZCBvbmUgaXMgbm8gZ2F0ZS5cbiAqL1xuY29uc3QgTEFLRUJBU0VfUkVTT0xWRV9USU1FT1VUX01TID0gNjBfMDAwO1xuXG4vKipcbiAqIEZpbGwgaW4gdGhlIExha2ViYXNlIGNvbm5lY3Rpb24gZW52IEFwcEtpdCdzIGNhY2hlIG5lZWRzLCBzbyBgQ2FjaGVNYW5hZ2VyYFxuICogY2hvb3NlcyBQRVJTSVNURU5UIHN0b3JhZ2UgaW5zdGVhZCBvZiBtZW1vcnkuXG4gKlxuICogVGhpcyBpcyB3aGF0IG1ha2VzIHRoZSBnYXRlJ3Mgc2Vzc2lvbiBzaWduaW5nIGtleSBhbmQgb3V0c3RhbmRpbmcgb25lLXRpbWVcbiAqIGNvZGVzIHN1cnZpdmUgYSByZXN0YXJ0LiBgYXBwbHlMYWtlYmFzZUVudmAgaXMgdGhlIFNIQVJFRCBoZWxwZXIgQXBwS2l0XG4gKiBhdXRvLWNvbmZpZ3VyYXRpb24gdXNlcywgc28gdGhlIGdhdGUgZ2V0cyBleGFjdGx5IHRoZSBlbnYgYSBwb29sIG5lZWRzIC1cbiAqIGBMQUtFQkFTRV9FTkRQT0lOVGAsIGBQR0hPU1RgLCBgUEdEQVRBQkFTRWAsIGFuZCBgUEdVU0VSYCAtIHJhdGhlciB0aGFuIGFcbiAqIGhhbmQtcm9sbGVkIHN1YnNldC4gQWxsIGZvdXIgbWF0dGVyOiBgY3JlYXRlTGFrZWJhc2VQb29sKClgIHRocm93cyB3aXRob3V0IGFueVxuICogb25lIG9mIHRoZW0sIGFuZCBhIERhdGFicmlja3MgQXBwIGBwb3N0Z3Jlc2AgcmVzb3VyY2UgYmluZGluZyBzdXBwbGllcyBvbmx5IHRoZVxuICogZmlyc3QuIFdpdGhvdXQgdGhlbSB0aGUgcG9vbCBjYW5ub3QgYmUgYnVpbHQsIHRoZSBjYWNoZSBzaWxlbnRseSBkZWdyYWRlcyB0b1xuICogaW4tbWVtb3J5LCBhbmQgZXZlcnkgcmVkZXBsb3kgc2lnbnMgb3V0IGV2ZXJ5IHVzZXIgKHRoZSBleGFjdCBzeW1wdG9tIHRoaXNcbiAqIGV4aXN0cyB0byBwcmV2ZW50KS5cbiAqXG4gKiBJdCBpcyBjYWxsZWQgaGVyZSByYXRoZXIgdGhhbiBsZWZ0IHRvIGBjcmVhdGVBcHBgJ3MgYGF1dG9Db25maWd1cmVgIGJlY2F1c2UgdGhhdFxuICogZ2F0ZXMgb24gYSBgbGFrZWJhc2UoKWAgcGx1Z2luIGJlaW5nIHJlZ2lzdGVyZWQgLSBhbmQgdGhpcyBhcHAgcmVnaXN0ZXJzIG5vbmUsXG4gKiBoYXZpbmcgbm8gc2VydmVyIHRvIG1vdW50IExha2ViYXNlIHJvdXRlcyBvbi4gQ2FsbGluZyB0aGUgaGVscGVyIGRpcmVjdGx5IGFsc29cbiAqIGxldHMgdGhlIGdhdGUgYmUgc3RyaWN0ZXIgdGhhbiBgYXV0b0NvbmZpZ3VyZWAgaXM6XG4gKlxuICogICAtIEl0IHJ1bnMgT05MWSB3aGVuIGEgTGFrZWJhc2UgZW52IHZhciBpcyBwcmVzZW50LiBBIHR1bm5lbCBpcyBhIHdyYXBwZXJcbiAqICAgICBhcm91bmQgc29tZW9uZSBlbHNlJ3MgYXBwIGFuZCBtdXN0IG5vdCBpbnZlbnQgaW5mcmFzdHJ1Y3R1cmUsIHNvIHdpdGhcbiAqICAgICBub3RoaW5nIGJvdW5kIGl0IHNraXBzIHJhdGhlciB0aGFuIGZhbGxpbmcgdGhyb3VnaCB0aGUgcmVzb2x2ZXInc1xuICogICAgIGxpc3Qtb3ItQ1JFQVRFLWEtcHJvamVjdCBwYXRoLlxuICogICAtIGBhdXRvQ3JlYXRlOiBmYWxzZWAgZm9yIHRoZSBzYW1lIHJlYXNvbiwgaW4gY2FzZSBhIHByb2plY3QgaGFwcGVucyB0byBleGlzdC5cbiAqICAgLSBFdmVyeSBmYWlsdXJlIGlzIGEgV0FSTklORywgbmV2ZXIgYSB0aHJvdy4gVGhlIGNhY2hlIGlzIGFuIG9wdGltaXphdGlvbiBmb3JcbiAqICAgICBzZXNzaW9uIGR1cmFiaWxpdHk7IGFkbWlzc2lvbiBzdGlsbCByZXF1aXJlcyBhIGNvZGUgZGVsaXZlcmVkIHRvIGFuXG4gKiAgICAgYWxsb3ctbGlzdGVkIGFkZHJlc3MsIHNvIGEgZ2F0ZSB3aXRoIGEgbWVtb3J5IGNhY2hlIGlzIHNhZmUsIGp1c3QgZm9yZ2V0ZnVsLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVzb2x2ZUNhY2hlU3RvcmFnZUVudigpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgaWYgKCFlbnYudGV4dChMQUtFQkFTRV9FTlYpKSB7XG4gICAgbG9nZ2VyLmluZm8oXG4gICAgICBgbm8gJHtlbnYubmFtZShMQUtFQkFTRV9FTlYpfSAtIHRoZSBnYXRlIGNhY2hlIHN0YXlzIGluIG1lbW9yeTsgc2Vzc2lvbnMgYW5kIGNvZGVzIHdpbGwgbm90IHN1cnZpdmUgYSByZXN0YXJ0YCxcbiAgICApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICB0cnkge1xuICAgIGNvbnN0IHsgcmVzb2x2ZWQsIHVzZXIgfSA9IGF3YWl0IGFwcGx5TGFrZWJhc2VFbnYoXG4gICAgICB7IGF1dG9DcmVhdGU6IGZhbHNlIH0sXG4gICAgICBBYm9ydFNpZ25hbC50aW1lb3V0KExBS0VCQVNFX1JFU09MVkVfVElNRU9VVF9NUyksXG4gICAgKTtcbiAgICBsb2dnZXIuaW5mbyhcImxha2ViYXNlIHJlc29sdmVkIGZvciB0aGUgZ2F0ZSBjYWNoZVwiLCB7XG4gICAgICBob3N0OiByZXNvbHZlZC5ob3N0LFxuICAgICAgZGF0YWJhc2U6IHJlc29sdmVkLmRhdGFiYXNlLFxuICAgICAgZW5kcG9pbnQ6IHJlc29sdmVkLmVuZHBvaW50LFxuICAgICAgdXNlcixcbiAgICB9KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBsb2dnZXIud2FybihcbiAgICAgIFwiY291bGQgbm90IHJlc29sdmUgbGFrZWJhc2UgLSB0aGUgZ2F0ZSBjYWNoZSBzdGF5cyBpbiBtZW1vcnk7IHNlc3Npb25zIGFuZCBjb2RlcyB3aWxsIG5vdCBzdXJ2aXZlIGEgcmVzdGFydFwiLFxuICAgICAgeyBlcnJvciB9LFxuICAgICk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogQm9vdCB0aGUgZ2F0ZSBhcHAgYW5kIHJldHVybiB0aGUgQVBJIHRoZSBwcm94eSBjYWxscy4gVGhyb3dzIHdoZW4gZW1haWwgaXMgbm90XG4gKiBpbiBTTVRQIG1vZGUgKG5vIHdheSB0byBkZWxpdmVyIGEgY29kZSkgc28gYSBtaXNjb25maWd1cmVkIGdhdGUgZmFpbHMgZmFzdCBhdFxuICogc3RhcnR1cCByYXRoZXIgdGhhbiBzaWxlbnRseSBhY2NlcHRpbmcgbm9ib2R5OyB0aGUgY2FsbGVyIG1heSBjYXRjaCB0aGlzIGFuZFxuICogZmFsbCBiYWNrIHRvIGluc2VjdXJlL29wZW4gbW9kZSB3aGVuIHRoZSBvcGVyYXRvciBvcHRlZCBpbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHN0YXJ0R2F0ZUFwcChjb25maWc6IEF1dGhHYXRlQ29uZmlnKTogUHJvbWlzZTxBdXRoR2F0ZUFwaT4ge1xuICAvLyBUaGUgaG9zdCBhcHAncyBvd24gYnJhbmQgKGBicmFuZGluZy9icmFuZC55YW1sYCBkaXNjb3ZlcmVkIGZyb20gY3dkKSBvciB0aGVcbiAgLy8gZGJ4LXRvb2xzIGRlZmF1bHQuIFRoaXMgaXMgdGhlIE9ORSBicmFuZCBzb3VyY2UgZm9yIHRoZSBnYXRlOiBpdCBzdHlsZXMgdGhlXG4gIC8vIGNvZGUgZW1haWwgKGFjY2VudCBiYW5kLCBmb250LCBsb2dvKSB2aWEgdGhlIGVtYWlsIHBsdWdpbiBBTkQgc3VwcGxpZXMgdGhlXG4gIC8vIGRpc3BsYXkgbmFtZSB0aGUgY29weSB1c2VzLCBzbyBhIGRlcGxveW1lbnQgdGhhdCB0aGVtZXMgaXRzIGFwcCB0aGVtZXMgaXRzXG4gIC8vIHNpZ24taW4gZW1haWwgd2l0aCBpdC4gQW4gZXhwbGljaXQgYGJyYW5kTmFtZWAgc3RpbGwgd2lucyAoc2VlIGJlbG93KS5cbiAgY29uc3QgY29udGV4dCA9IGF3YWl0IGxvYWRCcmFuZENvbnRleHQoKTtcblxuICAvLyBCZWZvcmUgYGNyZWF0ZUFwcGAsIGJlY2F1c2UgQXBwS2l0IHJlc29sdmVzIHRoZSBjYWNoZSdzIHN0b3JhZ2UgZHVyaW5nIGl0IGFuZFxuICAvLyByZWFkcyB0aGUgY29ubmVjdGlvbiBvdXQgb2YgYHByb2Nlc3MuZW52YCB3aGVuIGl0IGRvZXMuIFNlZSB0aGUgZnVuY3Rpb24nc1xuICAvLyBkb2NzIGZvciB3aHkgdGhlIGdhdGUgcmVzb2x2ZXMgdGhpcyBpdHNlbGYuXG4gIGF3YWl0IHJlc29sdmVDYWNoZVN0b3JhZ2VFbnYoKTtcblxuICAvLyBgc2VuZENvZGVgIGRlbGl2ZXJzIHRoZSBPVFAgdGhyb3VnaCB0aGUgZW1haWwgcGx1Z2luJ3MgU0hBUkVEIHRyYW5zcG9ydCwgd2hpY2hcbiAgLy8gdGhlIGBlbWFpbCgpYCBwbHVnaW4gcHJpbWVzIGR1cmluZyBpdHMgYHNldHVwKClgIChhd2FpdGVkIGJ5IGBjcmVhdGVBcHBgXG4gIC8vIGJlbG93KS4gVXNpbmcgdGhlIG1vZHVsZS1sZXZlbCBgc2VuZEVtYWlsYCBhdm9pZHMgYSBjaXJjdWxhciBkZXBlbmRlbmN5IG9uIHRoZVxuICAvLyBhcHAgaGFuZGxlJ3MgaW5mZXJyZWQgdHlwZS4gVGhlIGBGcm9tYCBpcyB0aGUgU1lTVEVNIHNlbmRlcjogYSB2ZXJpZmljYXRpb25cbiAgLy8gY29kZSBpcyBtYWNoaW5lLWdlbmVyYXRlZCBhbmQgdW5hbnN3ZXJhYmxlLCBzbyBpdCBtdXN0IG5vdCBhcnJpdmUgZnJvbSBhXG4gIC8vIHBlcnNvbidzIGFkZHJlc3MgaW52aXRpbmcgYSByZXBseS5cbiAgY29uc3Qgc2VuZENvZGU6IE5vbk51bGxhYmxlPEF1dGhHYXRlQ29uZmlnW1wic2VuZENvZGVcIl0+ID0gYXN5bmMgKHRvLCBjb2RlLCBvcHRzKSA9PiB7XG4gICAgY29uc3QgZnJvbSA9IHJlc29sdmVTeXN0ZW1TZW5kZXJBZGRyZXNzKGdldEVtYWlsUnVudGltZSgpLmNvbmZpZyk7XG4gICAgYXdhaXQgc2VuZEVtYWlsKFxuICAgICAge1xuICAgICAgICB0bzogW3RvXSxcbiAgICAgICAgLy8gVGhlIGNvZGUgcmlkZXMgaW4gdGhlIFNVQkpFQ1QgYW5kIHRoZSBwcmVoZWFkZXIsIG5vdCBqdXN0IHRoZSBib2R5OlxuICAgICAgICAvLyB0aG9zZSB0d28gc3RyaW5ncyBhcmUgdGhlIHdob2xlIG9mIGEgcHVzaCBub3RpZmljYXRpb24sIGFuZCBhXG4gICAgICAgIC8vIG5vdGlmaWNhdGlvbiBpcyB3aGF0IG1vYmlsZSBhdXRvZmlsbCByZWFkcy4gU2VlIGBjb2RlRW1haWxTdWJqZWN0YC5cbiAgICAgICAgc3ViamVjdDogY29kZUVtYWlsU3ViamVjdChjb2RlLCBvcHRzLnN1YmplY3QpLFxuICAgICAgICBib2R5OiBjb2RlRW1haWxIdG1sQm9keShjb2RlLCBvcHRzKSxcbiAgICAgIH0sXG4gICAgICBmcm9tLFxuICAgICAgdW5kZWZpbmVkLFxuICAgICAgeyB0ZXh0OiBjb2RlRW1haWxUZXh0Qm9keShjb2RlLCBvcHRzKSwgcHJldmlldzogY29kZUVtYWlsUHJldmlldyhjb2RlLCBvcHRzKSB9LFxuICAgICk7XG4gIH07XG5cbiAgLy8gYGNyZWF0ZUFwcGAgbmFtZXNwYWNlcyBlYWNoIHBsdWdpbidzIGV4cG9ydHMgb24gdGhlIGhhbmRsZSBieSBtYW5pZmVzdCBuYW1lO1xuICAvLyBgaGFuZGxlLmF1dGhHYXRlYCBpcyB0aGUgaW4tcHJvY2VzcyBnYXRlIEFQSSB0aGUgcHJveHkgZHJpdmVzLlxuICAvL1xuICAvLyBgYXV0b0NvbmZpZ3VyZTogZmFsc2VgIGJlY2F1c2Uge0BsaW5rIHJlc29sdmVDYWNoZVN0b3JhZ2VFbnZ9IGFib3ZlIGFscmVhZHlcbiAgLy8gcmFuIHRoZSBvbmUgcGllY2Ugb2YgaXQgdGhpcyBhcHAgd2FudHMgKGBhcHBseUxha2ViYXNlRW52YCksIG9uIHRoaXMgYXBwJ3NcbiAgLy8gdGVybXMgLSBubyBhdXRvLWNyZWF0ZSwgYW5kIGEgd2FybmluZyBpbnN0ZWFkIG9mIGEgdGhyb3cuXG4gIGNvbnN0IGhhbmRsZSA9IGF3YWl0IGNyZWF0ZUFwcCh7XG4gICAgYXV0b0NvbmZpZ3VyZTogZmFsc2UsXG4gICAgcGx1Z2luczogW1xuICAgICAgLy8gQnJhbmQgdGhlIGNvZGUgZW1haWwgZnJvbSB0aGUgcmVzb2x2ZWQgY29udGV4dCwgdGhlIHNhbWUgYnJpZGdlIGV2ZXJ5XG4gICAgICAvLyBvdGhlciBkYngtdG9vbHMgZW1haWwgc3VyZmFjZSB1c2VzIChhY2NlbnQgKyBmb250IGlubGluZWQsIGxvZ28gb25seSB3aGVuXG4gICAgICAvLyBpdCBpcyBhIGZldGNoYWJsZSBVUkwgLSBhIHBhY2thZ2UtZXhwb3J0IHBhdGggY2Fubm90IGxvYWQgaW4gYW4gaW5ib3gpLlxuICAgICAgZW1haWwoeyBicmFuZDogZW1haWxCcmFuZEZyb21Db250ZXh0KGNvbnRleHQpIH0pLFxuICAgICAgLy8gYGJyYW5kTmFtZWAgZmFsbHMgYmFjayB0byB0aGUgcmVzb2x2ZWQgY29udGV4dCdzIGRpc3BsYXkgbmFtZSwgc28gdGhlXG4gICAgICAvLyBlbWFpbCBjb3B5IG5hbWVzIHRoZSBhcHAgcmF0aGVyIHRoYW4gYSBnZW5lcmljIHBsYWNlaG9sZGVyLiBTcGVsbGVkIGFzIGFuXG4gICAgICAvLyBleHBsaWNpdCBgPz9gIHJhdGhlciB0aGFuIGEga2V5IGJlZm9yZSBgLi4uY29uZmlnYDogY29tbWFuZGVyIHNldHNcbiAgICAgIC8vIGBicmFuZE5hbWVgIG9uIHRoZSBvcHRpb25zIG9iamVjdCB3aGV0aGVyIG9yIG5vdCB0aGUgZmxhZyB3YXMgcGFzc2VkLCBzb1xuICAgICAgLy8gc3ByZWFkaW5nIGl0IHdvdWxkIGNsb2JiZXIgdGhlIGNvbnRleHQgbmFtZSB3aXRoIGB1bmRlZmluZWRgLlxuICAgICAgYXV0aEdhdGUoeyAuLi5jb25maWcsIGJyYW5kTmFtZTogY29uZmlnLmJyYW5kTmFtZSA/PyBjb250ZXh0Lm5hbWUsIHNlbmRDb2RlIH0pLFxuICAgIF0sXG4gIH0pO1xuXG4gIC8vIEZhaWwgZmFzdDogdGhlIGdhdGUgbmVlZHMgU01UUCB0byBlbWFpbCBjb2Rlcy4gYGdldEVtYWlsUnVudGltZSgpYCByZXNvbHZlcyB0b1xuICAvLyBgbW9kZTogXCJmaWxlXCJgIChvdXRib3gpIG9yIHRocm93cyB3aGVuIG5vIFNNVFAgY3JlZHMgYXJlIGNvbmZpZ3VyZWQgLSBuZWl0aGVyXG4gIC8vIGNhbiBkZWxpdmVyIHRvIGEgcmVhbCBpbmJveCwgc28gcmVmdXNlIHRvIGJyaW5nIHVwIGEgZ2F0ZSB0aGF0IGxldHMgbm9ib2R5IGluLlxuICBpZiAoZ2V0RW1haWxSdW50aW1lKCkuY29uZmlnLm1vZGUgIT09IFwic210cFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgXCJlbWFpbCBpcyBub3QgY29uZmlndXJlZCBmb3IgU01UUCBkZWxpdmVyeSAtIHRoZSBPVFAgZ2F0ZSBjYW5ub3Qgc2VuZCBjb2Rlcy4gXCIgK1xuICAgICAgICBcIlNldCBTTVRQX0hPU1QvU01UUF9VU0VSL1NNVFBfUEFTU1dPUkQsIG9yIHBhc3MgLS1pbnNlY3VyZSAvIFRVTk5FTF9JTlNFQ1VSRT10cnVlIHRvIHJ1biB0aGUgdHVubmVsIG9wZW4uXCIsXG4gICAgKTtcbiAgfVxuXG4gIGxvZ2dlci5pbmZvKFwiZ2F0ZSBhcHAgcmVhZHkgKG5vIHNlcnZlcjsgcHJveHktZHJpdmVuKVwiKTtcbiAgcmV0dXJuIGhhbmRsZS5hdXRoR2F0ZSBhcyBBdXRoR2F0ZUFwaTtcbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@clack/prompts": "^1.7.0",
|
|
31
31
|
"@databricks/appkit": "^0.43.0",
|
|
32
|
-
"@dbx-tools/appkit": "0.6.
|
|
33
|
-
"@dbx-tools/core": "0.6.
|
|
34
|
-
"@dbx-tools/email": "0.6.
|
|
35
|
-
"@dbx-tools/shared-core": "0.6.
|
|
36
|
-
"@dbx-tools/shared-email": "0.6.
|
|
32
|
+
"@dbx-tools/appkit": "0.6.59",
|
|
33
|
+
"@dbx-tools/core": "0.6.59",
|
|
34
|
+
"@dbx-tools/email": "0.6.59",
|
|
35
|
+
"@dbx-tools/shared-core": "0.6.59",
|
|
36
|
+
"@dbx-tools/shared-email": "0.6.59",
|
|
37
37
|
"commander": "^15.0.0",
|
|
38
38
|
"http-proxy-3": "^1.23.3",
|
|
39
39
|
"jose": "^6.2.3"
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"./package.json": "./package.json"
|
|
101
101
|
}
|
|
102
102
|
},
|
|
103
|
-
"version": "0.6.
|
|
103
|
+
"version": "0.6.59",
|
|
104
104
|
"types": "./lib/index.d.ts",
|
|
105
105
|
"type": "module",
|
|
106
106
|
"exports": {
|
package/src/app.ts
CHANGED
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
* @module
|
|
26
26
|
*/
|
|
27
27
|
|
|
28
|
-
import { getUsernameWithApiLookup } from "@databricks/appkit";
|
|
29
28
|
import { createApp as createAppNs, lakebaseResolver } from "@dbx-tools/appkit";
|
|
30
29
|
import { brand as nodeBrand } from "@dbx-tools/core";
|
|
31
30
|
import { brand as emailBrand, email, sender, transport } from "@dbx-tools/email";
|
|
@@ -138,7 +137,7 @@ export function codeEmailPreview(code: string, opts: CodeCopy): string {
|
|
|
138
137
|
}
|
|
139
138
|
|
|
140
139
|
const { createApp } = createAppNs;
|
|
141
|
-
const {
|
|
140
|
+
const { applyLakebaseEnv } = lakebaseResolver;
|
|
142
141
|
const { resolveSystemSenderAddress } = sender;
|
|
143
142
|
const { getEmailRuntime, sendEmail } = transport;
|
|
144
143
|
const { emailBrandFromContext } = emailBrand;
|
|
@@ -163,22 +162,19 @@ const LAKEBASE_RESOLVE_TIMEOUT_MS = 60_000;
|
|
|
163
162
|
* chooses PERSISTENT storage instead of memory.
|
|
164
163
|
*
|
|
165
164
|
* This is what makes the gate's session signing key and outstanding one-time
|
|
166
|
-
* codes survive a restart
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
*
|
|
174
|
-
* developer on a PAT, with no `DATABRICKS_CLIENT_ID`) is always missing. Without
|
|
175
|
-
* all four the pool cannot be built, the cache silently degrades to in-memory, and
|
|
176
|
-
* every redeploy signs out every user (the exact symptom this exists to prevent).
|
|
165
|
+
* codes survive a restart. `applyLakebaseEnv` is the SHARED helper AppKit
|
|
166
|
+
* auto-configuration uses, so the gate gets exactly the env a pool needs -
|
|
167
|
+
* `LAKEBASE_ENDPOINT`, `PGHOST`, `PGDATABASE`, and `PGUSER` - rather than a
|
|
168
|
+
* hand-rolled subset. All four matter: `createLakebasePool()` throws without any
|
|
169
|
+
* one of them, and a Databricks App `postgres` resource binding supplies only the
|
|
170
|
+
* first. Without them the pool cannot be built, the cache silently degrades to
|
|
171
|
+
* in-memory, and every redeploy signs out every user (the exact symptom this
|
|
172
|
+
* exists to prevent).
|
|
177
173
|
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
174
|
+
* It is called here rather than left to `createApp`'s `autoConfigure` because that
|
|
175
|
+
* gates on a `lakebase()` plugin being registered - and this app registers none,
|
|
176
|
+
* having no server to mount Lakebase routes on. Calling the helper directly also
|
|
177
|
+
* lets the gate be stricter than `autoConfigure` is:
|
|
182
178
|
*
|
|
183
179
|
* - It runs ONLY when a Lakebase env var is present. A tunnel is a wrapper
|
|
184
180
|
* around someone else's app and must not invent infrastructure, so with
|
|
@@ -197,21 +193,15 @@ export async function resolveCacheStorageEnv(): Promise<boolean> {
|
|
|
197
193
|
return false;
|
|
198
194
|
}
|
|
199
195
|
try {
|
|
200
|
-
const resolved = await
|
|
196
|
+
const { resolved, user } = await applyLakebaseEnv(
|
|
201
197
|
{ autoCreate: false },
|
|
202
198
|
AbortSignal.timeout(LAKEBASE_RESOLVE_TIMEOUT_MS),
|
|
203
199
|
);
|
|
204
|
-
applyLakebaseToEnv(resolved);
|
|
205
|
-
// `??=` so an explicitly configured PGUSER stays authoritative. The lookup
|
|
206
|
-
// falls back to the workspace API and returns undefined rather than throwing,
|
|
207
|
-
// so a failure here just leaves the pool to find its own username.
|
|
208
|
-
const user = await getUsernameWithApiLookup({});
|
|
209
|
-
if (user) process.env.PGUSER ??= user;
|
|
210
200
|
logger.info("lakebase resolved for the gate cache", {
|
|
211
201
|
host: resolved.host,
|
|
212
202
|
database: resolved.database,
|
|
213
203
|
endpoint: resolved.endpoint,
|
|
214
|
-
user
|
|
204
|
+
user,
|
|
215
205
|
});
|
|
216
206
|
return true;
|
|
217
207
|
} catch (error) {
|
|
@@ -269,7 +259,8 @@ export async function startGateApp(config: AuthGateConfig): Promise<AuthGateApi>
|
|
|
269
259
|
// `handle.authGate` is the in-process gate API the proxy drives.
|
|
270
260
|
//
|
|
271
261
|
// `autoConfigure: false` because {@link resolveCacheStorageEnv} above already
|
|
272
|
-
//
|
|
262
|
+
// ran the one piece of it this app wants (`applyLakebaseEnv`), on this app's
|
|
263
|
+
// terms - no auto-create, and a warning instead of a throw.
|
|
273
264
|
const handle = await createApp({
|
|
274
265
|
autoConfigure: false,
|
|
275
266
|
plugins: [
|