@dbx-tools/appkit 0.6.112 → 0.6.113
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 +6 -5
- package/lib/src/interceptor.d.ts +2 -0
- package/lib/src/interceptor.js +45 -33
- package/package.json +4 -4
- package/src/interceptor.ts +45 -31
package/README.md
CHANGED
|
@@ -22,10 +22,11 @@ without taking on a heavier feature package.
|
|
|
22
22
|
be granted access before persistent cache initialization.
|
|
23
23
|
- An interceptor context on `createApp` (`interceptor?: Interceptor | Interceptor[]`)
|
|
24
24
|
that hands add-ons the computed env, AppKit lifecycle hooks (`onLifecycle`, using
|
|
25
|
-
AppKit's own `setup:complete` / `server:ready` / `shutdown` vocabulary),
|
|
26
|
-
broadcast, and `bindProcess` for
|
|
27
|
-
|
|
28
|
-
|
|
25
|
+
AppKit's own `setup:complete` / `server:ready` / `shutdown` vocabulary),
|
|
26
|
+
synchronous `onTeardown` cleanup, signal broadcast, and `bindProcess` for
|
|
27
|
+
concurrently-style child supervision. Every interceptor context shares one
|
|
28
|
+
process group: any bound process's death tears down every sibling and signals
|
|
29
|
+
pass through. `@dbx-tools/tunnel` and `@dbx-tools/appkit-graphiti` consume it.
|
|
29
30
|
|
|
30
31
|
## Why Use This Over Native AppKit
|
|
31
32
|
|
|
@@ -115,7 +116,7 @@ reason.
|
|
|
115
116
|
| Option | Type | Default | Description |
|
|
116
117
|
| --------------- | ------------------------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
117
118
|
| `autoConfigure` | `"provision" \| "env" \| false` | `"provision"` | What to run before AppKit boots. `"provision"` resolves the Lakebase connection into `process.env` and grants the AppKit cache schema; `"env"` resolves the connection only; `false` skips auto-configuration. Omit it to gate the default on a `lakebase` plugin being registered, or set it explicitly to run regardless. |
|
|
118
|
-
| `interceptor` | `Interceptor \| Interceptor[]` | none | One or many callbacks handed an `InterceptorContext` after auto-config computes the env and before AppKit boots. The context carries the resolved env, `onLifecycle
|
|
119
|
+
| `interceptor` | `Interceptor \| Interceptor[]` | none | One or many callbacks handed an `InterceptorContext` after auto-config computes the env and before AppKit boots. The context carries the resolved env, `onLifecycle`, `onTeardown`, `broadcastSignal`, and globally shared `bindProcess` supervision. |
|
|
119
120
|
|
|
120
121
|
Set `autoConfigure` explicitly on an app that registers no `lakebase()` plugin but
|
|
121
122
|
still wants AppKit's PERSISTENT cache. AppKit only chooses Lakebase for
|
package/lib/src/interceptor.d.ts
CHANGED
|
@@ -84,6 +84,8 @@ export interface InterceptorContext {
|
|
|
84
84
|
* retroactively (same semantics as AppKit).
|
|
85
85
|
*/
|
|
86
86
|
onLifecycle(event: LifecycleEvent, fn: LifecycleHandler): void;
|
|
87
|
+
/** Register synchronous cleanup that runs before any bound process is killed. */
|
|
88
|
+
onTeardown(fn: () => void): void;
|
|
87
89
|
/**
|
|
88
90
|
* Broadcast a termination signal from the main app to every bound process.
|
|
89
91
|
* Called automatically when this process receives `SIGINT`/`SIGTERM`/`SIGHUP`;
|
package/lib/src/interceptor.js
CHANGED
|
@@ -23,9 +23,42 @@ import { Plugin, toPlugin } from "@databricks/appkit";
|
|
|
23
23
|
import { log } from "@dbx-tools/shared-core";
|
|
24
24
|
const logger = log.logger("interceptor");
|
|
25
25
|
/** How long bound children get to exit on `SIGTERM` before the app force-exits. */
|
|
26
|
-
const TEARDOWN_GRACE_MS =
|
|
26
|
+
const TEARDOWN_GRACE_MS = 10_000;
|
|
27
27
|
/** The signals that trigger teardown when the MAIN process receives them. */
|
|
28
28
|
const TEARDOWN_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
29
|
+
const boundChildren = new Set();
|
|
30
|
+
const teardownHandlers = new Set();
|
|
31
|
+
let processShuttingDown = false;
|
|
32
|
+
let processSignalsBound = false;
|
|
33
|
+
function teardownProcess(code) {
|
|
34
|
+
if (processShuttingDown)
|
|
35
|
+
return;
|
|
36
|
+
processShuttingDown = true;
|
|
37
|
+
for (const handler of teardownHandlers)
|
|
38
|
+
handler();
|
|
39
|
+
teardownHandlers.clear();
|
|
40
|
+
for (const child of boundChildren) {
|
|
41
|
+
if (!child.killed)
|
|
42
|
+
child.kill("SIGTERM");
|
|
43
|
+
}
|
|
44
|
+
boundChildren.clear();
|
|
45
|
+
setTimeout(() => process.exit(code), TEARDOWN_GRACE_MS).unref();
|
|
46
|
+
}
|
|
47
|
+
function broadcastProcessSignal(signal) {
|
|
48
|
+
for (const child of boundChildren) {
|
|
49
|
+
if (!child.killed)
|
|
50
|
+
child.kill(signal);
|
|
51
|
+
}
|
|
52
|
+
teardownProcess(0);
|
|
53
|
+
}
|
|
54
|
+
function bindProcessSignals() {
|
|
55
|
+
if (processSignalsBound)
|
|
56
|
+
return;
|
|
57
|
+
processSignalsBound = true;
|
|
58
|
+
for (const signal of TEARDOWN_SIGNALS) {
|
|
59
|
+
process.on(signal, () => broadcastProcessSignal(signal));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
29
62
|
/**
|
|
30
63
|
* Build an {@link InterceptorContext} + its {@link InterceptorRuntime}.
|
|
31
64
|
*
|
|
@@ -37,40 +70,18 @@ const TEARDOWN_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"];
|
|
|
37
70
|
*/
|
|
38
71
|
export function createInterceptorContext(env) {
|
|
39
72
|
const handlers = new Map();
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
shuttingDown = true;
|
|
47
|
-
for (const child of children) {
|
|
48
|
-
if (!child.killed)
|
|
49
|
-
child.kill("SIGTERM");
|
|
50
|
-
}
|
|
51
|
-
setTimeout(() => process.exit(code), TEARDOWN_GRACE_MS).unref();
|
|
52
|
-
};
|
|
53
|
-
const broadcastSignal = (signal) => {
|
|
54
|
-
for (const child of children) {
|
|
55
|
-
if (!child.killed)
|
|
56
|
-
child.kill(signal);
|
|
57
|
-
}
|
|
58
|
-
teardown(0);
|
|
59
|
-
};
|
|
60
|
-
const bindProcessSignals = () => {
|
|
61
|
-
if (signalsBound)
|
|
62
|
-
return;
|
|
63
|
-
signalsBound = true;
|
|
64
|
-
for (const signal of TEARDOWN_SIGNALS) {
|
|
65
|
-
process.on(signal, () => broadcastSignal(signal));
|
|
66
|
-
}
|
|
67
|
-
};
|
|
73
|
+
if (processShuttingDown && boundChildren.size === 0)
|
|
74
|
+
processShuttingDown = false;
|
|
75
|
+
if (processSignalsBound &&
|
|
76
|
+
TEARDOWN_SIGNALS.every((signal) => process.listenerCount(signal) === 0)) {
|
|
77
|
+
processSignalsBound = false;
|
|
78
|
+
}
|
|
68
79
|
const bindProcess = (child) => {
|
|
69
80
|
bindProcessSignals();
|
|
70
|
-
|
|
81
|
+
boundChildren.add(child);
|
|
71
82
|
child.once("exit", (code) => {
|
|
72
83
|
logger.warn("bound process exited; tearing down the app", { code });
|
|
73
|
-
|
|
84
|
+
teardownProcess(typeof code === "number" ? code : 1);
|
|
74
85
|
});
|
|
75
86
|
};
|
|
76
87
|
const onLifecycle = (event, fn) => {
|
|
@@ -98,7 +109,8 @@ export function createInterceptorContext(env) {
|
|
|
98
109
|
const context = {
|
|
99
110
|
env,
|
|
100
111
|
onLifecycle,
|
|
101
|
-
|
|
112
|
+
onTeardown: (fn) => teardownHandlers.add(fn),
|
|
113
|
+
broadcastSignal: broadcastProcessSignal,
|
|
102
114
|
bindProcess,
|
|
103
115
|
};
|
|
104
116
|
return { context, emitLifecycle };
|
|
@@ -138,4 +150,4 @@ export class LifecycleBridgePlugin extends Plugin {
|
|
|
138
150
|
}
|
|
139
151
|
/** Factory for the injected {@link LifecycleBridgePlugin}. */
|
|
140
152
|
export const lifecycleBridge = toPlugin(LifecycleBridgePlugin);
|
|
141
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBR0gsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQThDLE1BQU0sb0JBQW9CLENBQUM7QUFDbEcsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzdDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7QUFxRnpDLG1GQUFtRjtBQUNuRixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQztBQUUvQiw2RUFBNkU7QUFDN0UsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFVLENBQUM7QUFjbEU7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsd0JBQXdCLENBQUMsR0FBbUI7SUFDMUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQXNDLENBQUM7SUFDL0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7SUFDNUMsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztJQUV6QixNQUFNLFFBQVEsR0FBRyxDQUFDLElBQVksRUFBUSxFQUFFO1FBQ3RDLElBQUksWUFBWTtZQUFFLE9BQU87UUFDekIsWUFBWSxHQUFHLElBQUksQ0FBQztRQUNwQixLQUFLLE1BQU0sS0FBSyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFDRCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxp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QixXQUFXLEVBQUUsc0VBQXNFO1FBQ25GLFNBQVMsRUFBRSxNQUFNO1FBQ2pCLE1BQU0sRUFBRSxJQUFJO1FBQ1osU0FBUyxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFO0tBQ1UsQ0FBQztJQUU3QyxLQUFLLENBQUMsS0FBSztRQUNsQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztRQUNwQyxJQUFJLENBQUMsT0FBTztZQUFFLE9BQU87UUFDckIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNsQyxNQUFNLENBQUMsS0FBSyxDQUFDLDRFQUE0RSxDQUFDLENBQUM7WUFDM0YsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBcUIsQ0FBQyxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDaEYsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7SUFDSCxDQUFDOztBQUdILDhEQUE4RDtBQUM5RCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsUUFBUSxDQUFDLHFCQUFxQixDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRoZSBgY3JlYXRlQXBwYCBJTlRFUkNFUFRPUiBjb250ZXh0OiBhbiBpbi1wcm9jZXNzIGhhbmRsZSBhbiBhcHAgaGFuZHMgdG9cbiAqIGFkZC1vbnMgKHRoZSB0dW5uZWwsIGNoaWVmbHkpIHNvIHRoZXkgY2FuIHJlYWQgdGhlIGVudiBhdXRvLWNvbmZpZ3VyYXRpb25cbiAqIGNvbXB1dGVkLCBob29rIEFwcEtpdCdzIGxpZmVjeWNsZSwgYW5kIHN1cGVydmlzZSBzaWJsaW5nIGNoaWxkIHByb2Nlc3NlcyBhcyBvbmVcbiAqIHVuaXQgLSBjb25jdXJyZW50bHktc3R5bGUsIHdoZXJlIGFueSBkZWF0aCB0YWtlcyB0aGUgd2hvbGUgc2V0IGRvd24uXG4gKlxuICogQW4gaW50ZXJjZXB0b3IgaXMgYSBwbGFpbiBmdW5jdGlvbiBgKGN0eCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD5gIHBhc3NlZCB0b1xuICogYGFwcGtpdC5jcmVhdGVBcHBgJ3MgYGludGVyY2VwdG9yYCBvcHRpb24gKFwib25lIG9yIG1hbnlcIikuIGBhcHBraXQuY3JlYXRlQXBwYFxuICogcnVucyBlYWNoIG9uZSBBRlRFUiBhdXRvLWNvbmZpZ3VyYXRpb24gaGFzIHBvcHVsYXRlZCBgcHJvY2Vzcy5lbnZgIGJ1dCBhcyBwYXJ0XG4gKiBvZiBib290aW5nIHRoZSBhcHAsIHNvIGFuIGludGVyY2VwdG9yIHNlZXMgdGhlIHJlc29sdmVkIGNvbm5lY3Rpb24gYW5kIGNhbiBiaW5kXG4gKiBwcm9jZXNzZXMgYmVmb3JlIG9yIGR1cmluZyBzZXR1cC5cbiAqXG4gKiBUaGUgbmFtZXMgaGVyZSBtaXJyb3IgQXBwS2l0J3Mgb3duIHZvY2FidWxhcnkgcmF0aGVyIHRoYW4gaW52ZW50aW5nIHBhcmFsbGVsXG4gKiBvbmVzOiB7QGxpbmsgTGlmZWN5Y2xlRXZlbnR9IGFuZCB7QGxpbmsgSW50ZXJjZXB0b3JDb250ZXh0Lm9uTGlmZWN5Y2xlfSBhcmUgdGhlXG4gKiBleGFjdCBzaGFwZSBvZiBgUGx1Z2luQ29udGV4dC5vbkxpZmVjeWNsZWAgKGBzZXR1cDpjb21wbGV0ZWAgLyBgc2VydmVyOnJlYWR5YCAvXG4gKiBgc2h1dGRvd25gKS4gVGhlIGJyaWRnZSB0aGF0IG1ha2VzIHRoYXQgaG9vayByZWFjaGFibGUgZnJvbSBPVVRTSURFIGEgcGx1Z2luIC1cbiAqIHdoZXJlIGludGVyY2VwdG9ycyBydW4gLSBpcyB7QGxpbmsgbGlmZWN5Y2xlQnJpZGdlfSwgYSB0aW55IGludGVybmFsIHBsdWdpblxuICogYGFwcGtpdC5jcmVhdGVBcHBgIGluamVjdHMgdG8gY2FwdHVyZSBgdGhpcy5jb250ZXh0YCBhbmQgcmVsYXkgaXRzIGV2ZW50cy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBDaGlsZFByb2Nlc3MgfSBmcm9tIFwibm9kZTpjaGlsZF9wcm9jZXNzXCI7XG5pbXBvcnQgeyBQbHVnaW4sIHRvUGx1Z2luLCB0eXBlIEJhc2VQbHVnaW5Db25maWcsIHR5cGUgUGx1Z2luTWFuaWZlc3QgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHR5cGUgeyBMYWtlYmFzZUNvbm5lY3Rpb24gfSBmcm9tIFwiLi9sYWtlYmFzZS1yZXNvbHZlci50c1wiO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwiaW50ZXJjZXB0b3JcIik7XG5cbi8qKlxuICogQXBwS2l0J3MgcGx1Z2luLWxpZmVjeWNsZSBldmVudHMsIHZlcmJhdGltIGZyb20gYFBsdWdpbkNvbnRleHRgXG4gKiAoYG5vZGVfbW9kdWxlcy9AZGF0YWJyaWNrcy9hcHBraXQvLi4uL2NvcmUvcGx1Z2luLWNvbnRleHQuZC50c2ApLiBSZS1kZWNsYXJlZFxuICogc3RydWN0dXJhbGx5IHJhdGhlciB0aGFuIGltcG9ydGVkIGJlY2F1c2UgYFBsdWdpbkNvbnRleHRgIGlzIG5vdCBpbiB0aGVcbiAqIHBhY2thZ2UncyBgZXhwb3J0c2AgbWFwICh0aGUgc2FtZSByZWFzb24ge0BsaW5rIFBsdWdpbkNvbnRleHRMaWtlfSBleGlzdHMgaW5cbiAqIGAuL3BsdWdpbmApLlxuICpcbiAqIC0gYHNldHVwOmNvbXBsZXRlYCAtIGV2ZXJ5IHBsdWdpbidzIGBzZXR1cCgpYCBoYXMgcmVzb2x2ZWQuXG4gKiAtIGBzZXJ2ZXI6cmVhZHlgIC0gdGhlIGBzZXJ2ZXIoKWAgcGx1Z2luIGlzIGxpc3RlbmluZyAobmV2ZXIgZmlyZXMgZm9yIGFcbiAqICAgc2VydmVybGVzcyBhcHAsIGUuZy4gdGhlIHR1bm5lbCBnYXRlKS5cbiAqIC0gYHNodXRkb3duYCAtIHRoZSBhcHAgaXMgdGVhcmluZyBkb3duLlxuICovXG5leHBvcnQgdHlwZSBMaWZlY3ljbGVFdmVudCA9IFwic2V0dXA6Y29tcGxldGVcIiB8IFwic2VydmVyOnJlYWR5XCIgfCBcInNodXRkb3duXCI7XG5cbi8qKiBBIGxpZmVjeWNsZSBzdWJzY3JpYmVyLiBFcnJvcnMgYXJlIGxvZ2dlZCwgbm90IHByb3BhZ2F0ZWQgKG1hdGNoZXMgQXBwS2l0KS4gKi9cbmV4cG9ydCB0eXBlIExpZmVjeWNsZUhhbmRsZXIgPSAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcblxuLyoqXG4gKiBUaGUgZW52IGF1dG8tY29uZmlndXJhdGlvbiByZXNvbHZlZCBiZWZvcmUgYm9vdCwgZXhwb3NlZCB0byBpbnRlcmNlcHRvcnMgc29cbiAqIHRoZXkgcmVhZCBDT01QVVRFRCB2YWx1ZXMgaW5zdGVhZCBvZiByZS1yZWFkaW5nIGBwcm9jZXNzLmVudmAgdGhlbXNlbHZlcy5cbiAqXG4gKiBgbGFrZWJhc2VgIGlzIHRoZSByZXNvbHZlZCBQb3N0Z3JlcyBjb25uZWN0aW9uIHdoZW4gTGFrZWJhc2UgYXV0by1jb25maWcgcmFuXG4gKiAoc2VlIGBhcHBraXQuYXV0b0NvbmZpZ3VyZWApLCBlbHNlIGB1bmRlZmluZWRgLiBgZGF0YWJyaWNrc0hvc3RgIGlzIHRoZVxuICogd29ya3NwYWNlIGhvc3QgYXMgcmVzb2x2ZWQgaW50byB0aGUgZW52aXJvbm1lbnQgKGBEQVRBQlJJQ0tTX0hPU1RgKSwgd2hpY2ggdGhlXG4gKiB0dW5uZWwgaW50ZXJjZXB0b3IgYm90aCByZWFkcyBhbmQsIHdoZW4gaXQgbXVzdCwgc2V0cy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZEFwcEVudiB7XG4gIC8qKiBSZXNvbHZlZCBMYWtlYmFzZSBjb25uZWN0aW9uLCB3aGVuIGF1dG8tY29uZmlnIHJlc29sdmVkIG9uZS4gKi9cbiAgcmVhZG9ubHkgbGFrZWJhc2U/OiBMYWtlYmFzZUNvbm5lY3Rpb247XG4gIC8qKiBSZXNvbHZlZCBEYXRhYnJpY2tzIHdvcmtzcGFjZSBob3N0IChgREFUQUJSSUNLU19IT1NUYCksIHdoZW4ga25vd24uICovXG4gIHJlYWRvbmx5IGRhdGFicmlja3NIb3N0Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgcHJvY2VzcyB7QGxpbmsgSW50ZXJjZXB0b3JDb250ZXh0LmJpbmRQcm9jZXNzfSBjYW4gc3VwZXJ2aXNlLiBBIGJhcmVcbiAqIGBub2RlOmNoaWxkX3Byb2Nlc3NgIGBDaGlsZFByb2Nlc3NgIChlLmcuIHBvcnRyKSBzYXRpc2ZpZXMgdGhpcywgYW5kIHNvIGRvZXNcbiAqIGBAZGJ4LXRvb2xzL2NvcmVgJ3MgYHNwYXduKClgIHJlc3VsdCAoYSBgQ2hpbGRQcm9jZXNzUmVzdWx0YCBJUyBhXG4gKiBgQ2hpbGRQcm9jZXNzYCkgLSBvbmUgY29kZSBwYXRoIGhhbmRsZXMgYm90aC5cbiAqL1xuZXhwb3J0IHR5cGUgQmluZGFibGVQcm9jZXNzID0gUGljazxDaGlsZFByb2Nlc3MsIFwicGlkXCIgfCBcImtpbGxcIiB8IFwia2lsbGVkXCIgfCBcIm9uY2VcIj47XG5cbi8qKlxuICogVGhlIGhhbmRsZSBwYXNzZWQgdG8gZWFjaCBpbnRlcmNlcHRvci5cbiAqXG4gKiBAZXhhbXBsZVxuICogaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG4gKlxuICogYXdhaXQgYXBwa2l0LmNyZWF0ZUFwcCh7XG4gKiAgIHBsdWdpbnM6IFtzZXJ2ZXIoKV0sXG4gKiAgIGludGVyY2VwdG9yOiAoY3R4KSA9PiB7XG4gKiAgICAgY29uc3QgcG9ydHIgPSBzcGF3blBvcnRyKGN0eC5lbnYuZGF0YWJyaWNrc0hvc3QpO1xuICogICAgIGN0eC5iaW5kUHJvY2Vzcyhwb3J0cik7ICAgICAgICAgICAgLy8gYXBwIDwtPiBwb3J0ciBsaXZlL2RpZSB0b2dldGhlclxuICogICAgIGN0eC5vbkxpZmVjeWNsZShcInNodXRkb3duXCIsICgpID0+IHBvcnRyLmtpbGwoXCJTSUdURVJNXCIpKTtcbiAqICAgfSxcbiAqIH0pO1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEludGVyY2VwdG9yQ29udGV4dCB7XG4gIC8qKiBUaGUgZW52IGF1dG8tY29uZmlndXJhdGlvbiBjb21wdXRlZCBiZWZvcmUgYm9vdC4gKi9cbiAgcmVhZG9ubHkgZW52OiBSZXNvbHZlZEFwcEVudjtcbiAgLyoqXG4gICAqIFN1YnNjcmliZSB0byBhbiBBcHBLaXQgbGlmZWN5Y2xlIGV2ZW50LiBNaXJyb3JzIGBQbHVnaW5Db250ZXh0Lm9uTGlmZWN5Y2xlYDtcbiAgICogdGhlIGluamVjdGVkIHtAbGluayBsaWZlY3ljbGVCcmlkZ2V9IHJlbGF5cyB0aGUgcmVhbCBldmVudHMgaGVyZSBvbmNlIHRoZSBhcHBcbiAgICogYm9vdHMuIEEgaGFuZGxlciByZWdpc3RlcmVkIGZvciBhbiBldmVudCB0aGF0IGFscmVhZHkgZmlyZWQgaXMgTk9UIGNhbGxlZFxuICAgKiByZXRyb2FjdGl2ZWx5IChzYW1lIHNlbWFudGljcyBhcyBBcHBLaXQpLlxuICAgKi9cbiAgb25MaWZlY3ljbGUoZXZlbnQ6IExpZmVjeWNsZUV2ZW50LCBmbjogTGlmZWN5Y2xlSGFuZGxlcik6IHZvaWQ7XG4gIC8qKlxuICAgKiBCcm9hZGNhc3QgYSB0ZXJtaW5hdGlvbiBzaWduYWwgZnJvbSB0aGUgbWFpbiBhcHAgdG8gZXZlcnkgYm91bmQgcHJvY2Vzcy5cbiAgICogQ2FsbGVkIGF1dG9tYXRpY2FsbHkgd2hlbiB0aGlzIHByb2Nlc3MgcmVjZWl2ZXMgYFNJR0lOVGAvYFNJR1RFUk1gL2BTSUdIVVBgO1xuICAgKiBleHBvc2VkIHNvIGFuIGludGVyY2VwdG9yIGNhbiB0cmlnZ2VyIHRlYXJkb3duIGl0c2VsZi5cbiAgICovXG4gIGJyb2FkY2FzdFNpZ25hbChzaWduYWw6IE5vZGVKUy5TaWduYWxzKTogdm9pZDtcbiAgLyoqXG4gICAqIFN1cGVydmlzZSBhIGNoaWxkIHByb2Nlc3MgYWxvbmdzaWRlIHRoZSBhcHAsIGNvbmN1cnJlbnRseS1zdHlsZTogc2lnbmFscyBwYXNzXG4gICAqIHRocm91Z2gsIGFuZCBpZiBFSVRIRVIgdGhlIGNoaWxkIG9yIHRoZSBhcHAgZGllcyB0aGUgd2hvbGUgc2V0IGNvbWVzIGRvd24uXG4gICAqIFNhZmUgdG8gY2FsbCBmb3Igc2V2ZXJhbCBjaGlsZHJlbjsgdGVhcmRvd24gaXMgaWRlbXBvdGVudC5cbiAgICovXG4gIGJpbmRQcm9jZXNzKGNoaWxkOiBCaW5kYWJsZVByb2Nlc3MpOiB2b2lkO1xufVxuXG4vKiogQSBzaW5nbGUgaW50ZXJjZXB0b3IsIG9yIHNldmVyYWwuIFRoZSBgY3JlYXRlQXBwYCBgaW50ZXJjZXB0b3I/OmAgb3B0aW9uLiAqL1xuZXhwb3J0IHR5cGUgSW50ZXJjZXB0b3IgPSAoY3R4OiBJbnRlcmNlcHRvckNvbnRleHQpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuXG4vKiogSG93IGxvbmcgYm91bmQgY2hpbGRyZW4gZ2V0IHRvIGV4aXQgb24gYFNJR1RFUk1gIGJlZm9yZSB0aGUgYXBwIGZvcmNlLWV4aXRzLiAqL1xuY29uc3QgVEVBUkRPV05fR1JBQ0VfTVMgPSAzMDAwO1xuXG4vKiogVGhlIHNpZ25hbHMgdGhhdCB0cmlnZ2VyIHRlYXJkb3duIHdoZW4gdGhlIE1BSU4gcHJvY2VzcyByZWNlaXZlcyB0aGVtLiAqL1xuY29uc3QgVEVBUkRPV05fU0lHTkFMUyA9IFtcIlNJR0lOVFwiLCBcIlNJR1RFUk1cIiwgXCJTSUdIVVBcIl0gYXMgY29uc3Q7XG5cbi8qKlxuICogVGhlIG11dGFibGUgbWFjaGluZXJ5IGJlaGluZCBhbiB7QGxpbmsgSW50ZXJjZXB0b3JDb250ZXh0fS4gU3BsaXQgb3V0IHNvXG4gKiB7QGxpbmsgY3JlYXRlSW50ZXJjZXB0b3JDb250ZXh0fSBjYW4gaGFuZCB0aGUgcHVibGljIGNvbnRleHQgdG8gaW50ZXJjZXB0b3JzXG4gKiB3aGlsZSBgYXBwa2l0LmNyZWF0ZUFwcGAgcmV0YWlucyB0aGUgYGVtaXRMaWZlY3ljbGVgIHNpZGUtY2hhbm5lbCB0aGUgYnJpZGdlIGRyaXZlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJbnRlcmNlcHRvclJ1bnRpbWUge1xuICAvKiogVGhlIGNvbnRleHQgaGFuZGVkIHRvIGVhY2ggaW50ZXJjZXB0b3IuICovXG4gIHJlYWRvbmx5IGNvbnRleHQ6IEludGVyY2VwdG9yQ29udGV4dDtcbiAgLyoqIEZpcmUgYSBsaWZlY3ljbGUgZXZlbnQgdG8gZXZlcnkgc3Vic2NyaWJlciAoY2FsbGVkIGJ5IHtAbGluayBsaWZlY3ljbGVCcmlkZ2V9KS4gKi9cbiAgZW1pdExpZmVjeWNsZShldmVudDogTGlmZWN5Y2xlRXZlbnQpOiBQcm9taXNlPHZvaWQ+O1xufVxuXG4vKipcbiAqIEJ1aWxkIGFuIHtAbGluayBJbnRlcmNlcHRvckNvbnRleHR9ICsgaXRzIHtAbGluayBJbnRlcmNlcHRvclJ1bnRpbWV9LlxuICpcbiAqIFRlYXJkb3duIGlzIHRoZSBnZW5lcmFsaXplZCBgc3VwZXJ2aXNlRXhpdGA6IHRoZSBmaXJzdCBjaGlsZCBleGl0IG9yIG1haW4tcHJvY2Vzc1xuICogdGVybWluYXRpb24gc2lnbmFsIGZsaXBzIGEgb25lLXNob3QgZ3VhcmQsIGBTSUdURVJNYHMgdGhlIG90aGVyIGJvdW5kIGNoaWxkcmVuLFxuICogdGhlbiBgcHJvY2Vzcy5leGl0YHMgYWZ0ZXIge0BsaW5rIFRFQVJET1dOX0dSQUNFX01TfSAoYW4gYHVucmVmYCdkIHRpbWVyLCBzbyBpdFxuICogbmV2ZXIgaXRzZWxmIGhvbGRzIHRoZSBsb29wIG9wZW4pLiBUaGUgcHJvY2Vzcy1zaWduYWwgbGlzdGVuZXJzIGFyZSBpbnN0YWxsZWRcbiAqIGxhemlseSBvbiB0aGUgZmlyc3QgYGJpbmRQcm9jZXNzYCBzbyBhbiBhcHAgdGhhdCBiaW5kcyBub3RoaW5nIGlzIHVudG91Y2hlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUludGVyY2VwdG9yQ29udGV4dChlbnY6IFJlc29sdmVkQXBwRW52KTogSW50ZXJjZXB0b3JSdW50aW1lIHtcbiAgY29uc3QgaGFuZGxlcnMgPSBuZXcgTWFwPExpZmVjeWNsZUV2ZW50LCBMaWZlY3ljbGVIYW5kbGVyW10+KCk7XG4gIGNvbnN0IGNoaWxkcmVuID0gbmV3IFNldDxCaW5kYWJsZVByb2Nlc3M+KCk7XG4gIGxldCBzaHV0dGluZ0Rvd24gPSBmYWxzZTtcbiAgbGV0IHNpZ25hbHNCb3VuZCA9IGZhbHNlO1xuXG4gIGNvbnN0IHRlYXJkb3duID0gKGNvZGU6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgIGlmIChzaHV0dGluZ0Rvd24pIHJldHVybjtcbiAgICBzaHV0dGluZ0Rvd24gPSB0cnVlO1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgY2hpbGRyZW4pIHtcbiAgICAgIGlmICghY2hpbGQua2lsbGVkKSBjaGlsZC5raWxsKFwiU0lHVEVSTVwiKTtcbiAgICB9XG4gICAgc2V0VGltZW91dCgoKSA9PiBwcm9jZXNzLmV4aXQoY29kZSksIFRFQVJET1dOX0dSQUNFX01TKS51bnJlZigpO1xuICB9O1xuXG4gIGNvbnN0IGJyb2FkY2FzdFNpZ25hbCA9IChzaWduYWw6IE5vZGVKUy5TaWduYWxzKTogdm9pZCA9PiB7XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBjaGlsZHJlbikge1xuICAgICAgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoc2lnbmFsKTtcbiAgICB9XG4gICAgdGVhcmRvd24oMCk7XG4gIH07XG5cbiAgY29uc3QgYmluZFByb2Nlc3NTaWduYWxzID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmIChzaWduYWxzQm91bmQpIHJldHVybjtcbiAgICBzaWduYWxzQm91bmQgPSB0cnVlO1xuICAgIGZvciAoY29uc3Qgc2lnbmFsIG9mIFRFQVJET1dOX1NJR05BTFMpIHtcbiAgICAgIHByb2Nlc3Mub24oc2lnbmFsLCAoKSA9PiBicm9hZGNhc3RTaWduYWwoc2lnbmFsKSk7XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IGJpbmRQcm9jZXNzID0gKGNoaWxkOiBCaW5kYWJsZVByb2Nlc3MpOiB2b2lkID0+IHtcbiAgICBiaW5kUHJvY2Vzc1NpZ25hbHMoKTtcbiAgICBjaGlsZHJlbi5hZGQoY2hpbGQpO1xuICAgIGNoaWxkLm9uY2UoXCJleGl0XCIsIChjb2RlKSA9PiB7XG4gICAgICBsb2dnZXIud2FybihcImJvdW5kIHByb2Nlc3MgZXhpdGVkOyB0ZWFyaW5nIGRvd24gdGhlIGFwcFwiLCB7IGNvZGUgfSk7XG4gICAgICB0ZWFyZG93bih0eXBlb2YgY29kZSA9PT0gXCJudW1iZXJcIiA/IGNvZGUgOiAxKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBvbkxpZmVjeWNsZSA9IChldmVudDogTGlmZWN5Y2xlRXZlbnQsIGZuOiBMaWZlY3ljbGVIYW5kbGVyKTogdm9pZCA9PiB7XG4gICAgY29uc3QgbGlzdCA9IGhhbmRsZXJzLmdldChldmVudCk7XG4gICAgaWYgKGxpc3QpIGxpc3QucHVzaChmbik7XG4gICAgZWxzZSBoYW5kbGVycy5zZXQoZXZlbnQsIFtmbl0pO1xuICB9O1xuXG4gIGNvbnN0IGVtaXRMaWZlY3ljbGUgPSBhc3luYyAoZXZlbnQ6IExpZmVjeWNsZUV2ZW50KTogUHJvbWlzZTx2b2lkPiA9PiB7XG4gICAgY29uc3QgbGlzdCA9IGhhbmRsZXJzLmdldChldmVudCk7XG4gICAgaWYgKCFsaXN0KSByZXR1cm47XG4gICAgZm9yIChjb25zdCBmbiBvZiBsaXN0KSB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBmbigpO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgLy8gTWF0Y2ggQXBwS2l0OiBhIGZhaWxpbmcgbGlmZWN5Y2xlIGhhbmRsZXIgaXMgbG9nZ2VkLCBuZXZlciBmYXRhbCwgYW5kXG4gICAgICAgIC8vIG5ldmVyIGJsb2NrcyBpdHMgc2libGluZ3MuXG4gICAgICAgIGxvZ2dlci53YXJuKFwibGlmZWN5Y2xlIGhhbmRsZXIgZmFpbGVkXCIsIHsgZXZlbnQsIGVycm9yIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBjb25zdCBjb250ZXh0OiBJbnRlcmNlcHRvckNvbnRleHQgPSB7XG4gICAgZW52LFxuICAgIG9uTGlmZWN5Y2xlLFxuICAgIGJyb2FkY2FzdFNpZ25hbCxcbiAgICBiaW5kUHJvY2VzcyxcbiAgfTtcblxuICByZXR1cm4geyBjb250ZXh0LCBlbWl0TGlmZWN5Y2xlIH07XG59XG5cbi8qKiBDb25maWcgZm9yIHtAbGluayBMaWZlY3ljbGVCcmlkZ2VQbHVnaW59OiB0aGUgc2luayBpdHMgY2FwdHVyZWQgZXZlbnRzIGZsb3cgdG8uICovXG5pbnRlcmZhY2UgTGlmZWN5Y2xlQnJpZGdlQ29uZmlnIGV4dGVuZHMgQmFzZVBsdWdpbkNvbmZpZyB7XG4gIC8qKiBUaGUgcnVudGltZSB3aG9zZSBgZW1pdExpZmVjeWNsZWAgcmVjZWl2ZXMgdGhlIHJlYWwgQXBwS2l0IGV2ZW50cy4gKi9cbiAgcnVudGltZT86IEludGVyY2VwdG9yUnVudGltZTtcbn1cblxuLyoqXG4gKiBTdHJ1Y3R1cmFsIHNoYXBlIG9mIHRoZSBgUGx1Z2luQ29udGV4dC5vbkxpZmVjeWNsZWAgd2UgYnJpZGdlLiBNaXJyb3JzIG9ubHkgdGhlXG4gKiBvbmUgbWV0aG9kIHdlIHRvdWNoIChsaWtlIHtAbGluayBQbHVnaW5Db250ZXh0TGlrZX0gaW4gYC4vcGx1Z2luYCksIHNpbmNlXG4gKiBBcHBLaXQncyBgUGx1Z2luQ29udGV4dGAgaXMgbm90IGltcG9ydGFibGUgZnJvbSB0aGUgcGFja2FnZSdzIGBleHBvcnRzYC5cbiAqL1xuaW50ZXJmYWNlIExpZmVjeWNsZUNvbnRleHRMaWtlIHtcbiAgb25MaWZlY3ljbGUoZXZlbnQ6IExpZmVjeWNsZUV2ZW50LCBmbjogTGlmZWN5Y2xlSGFuZGxlcik6IHZvaWQ7XG59XG5cbmZ1bmN0aW9uIGhhc09uTGlmZWN5Y2xlKGNvbnRleHQ6IHVua25vd24pOiBjb250ZXh0IGlzIExpZmVjeWNsZUNvbnRleHRMaWtlIHtcbiAgcmV0dXJuIHR5cGVvZiAoY29udGV4dCBhcyBMaWZlY3ljbGVDb250ZXh0TGlrZSB8IHVuZGVmaW5lZCk/Lm9uTGlmZWN5Y2xlID09PSBcImZ1bmN0aW9uXCI7XG59XG5cbi8qKlxuICogVGhlIGludGVybmFsIHBsdWdpbiBgYXBwa2l0LmNyZWF0ZUFwcGAgaW5qZWN0cyB0byBtYWtlIEFwcEtpdCdzIGxpZmVjeWNsZVxuICogcmVhY2hhYmxlIGZyb20gaW50ZXJjZXB0b3IgY29kZS4gT24gYHNldHVwKClgIGl0IHJlYWRzIGl0cyBvd24gYHRoaXMuY29udGV4dGBcbiAqICh0aGUgcmVhbCBgUGx1Z2luQ29udGV4dGApIGFuZCBmb3J3YXJkcyBlYWNoIHtAbGluayBMaWZlY3ljbGVFdmVudH0gdG8gdGhlXG4gKiBpbnRlcmNlcHRvciBydW50aW1lLCBzbyBgY3R4Lm9uTGlmZWN5Y2xlKC4uLilgIGhhbmRsZXJzIGZpcmUgb24gdGhlIGdlbnVpbmVcbiAqIGV2ZW50cy4gSXQgb3ducyBubyByb3V0ZXMsIGNvbmZpZyBzdXJmYWNlLCBvciBleHBvcnRzLlxuICovXG5leHBvcnQgY2xhc3MgTGlmZWN5Y2xlQnJpZGdlUGx1Z2luIGV4dGVuZHMgUGx1Z2luPExpZmVjeWNsZUJyaWRnZUNvbmZpZz4ge1xuICBzdGF0aWMgbWFuaWZlc3QgPSB7XG4gICAgbmFtZTogXCJkYnhUb29sc0xpZmVjeWNsZUJyaWRnZVwiLFxuICAgIGRpc3BsYXlOYW1lOiBcIkxpZmVjeWNsZSBCcmlkZ2VcIixcbiAgICBkZXNjcmlwdGlvbjogXCJSZWxheXMgQXBwS2l0IGxpZmVjeWNsZSBldmVudHMgdG8gdGhlIGNyZWF0ZUFwcCBpbnRlcmNlcHRvciBjb250ZXh0LlwiLFxuICAgIHN0YWJpbGl0eTogXCJiZXRhXCIsXG4gICAgaGlkZGVuOiB0cnVlLFxuICAgIHJlc291cmNlczogeyByZXF1aXJlZDogW10sIG9wdGlvbmFsOiBbXSB9LFxuICB9IHNhdGlzZmllcyBQbHVnaW5NYW5pZmVzdDxcImRieFRvb2xzTGlmZWN5Y2xlQnJpZGdlXCI+O1xuXG4gIG92ZXJyaWRlIGFzeW5jIHNldHVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJ1bnRpbWUgPSB0aGlzLmNvbmZpZy5ydW50aW1lO1xuICAgIGlmICghcnVudGltZSkgcmV0dXJuO1xuICAgIGlmICghaGFzT25MaWZlY3ljbGUodGhpcy5jb250ZXh0KSkge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwibm8gUGx1Z2luQ29udGV4dC5vbkxpZmVjeWNsZSB0byBicmlkZ2U7IGludGVyY2VwdG9yIGxpZmVjeWNsZSBldmVudHMgaW5lcnRcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGV2ZW50czogTGlmZWN5Y2xlRXZlbnRbXSA9IFtcInNldHVwOmNvbXBsZXRlXCIsIFwic2VydmVyOnJlYWR5XCIsIFwic2h1dGRvd25cIl07XG4gICAgZm9yIChjb25zdCBldmVudCBvZiBldmVudHMpIHtcbiAgICAgIHRoaXMuY29udGV4dC5vbkxpZmVjeWNsZShldmVudCwgKCkgPT4gcnVudGltZS5lbWl0TGlmZWN5Y2xlKGV2ZW50KSk7XG4gICAgfVxuICB9XG59XG5cbi8qKiBGYWN0b3J5IGZvciB0aGUgaW5qZWN0ZWQge0BsaW5rIExpZmVjeWNsZUJyaWRnZVBsdWdpbn0uICovXG5leHBvcnQgY29uc3QgbGlmZWN5Y2xlQnJpZGdlID0gdG9QbHVnaW4oTGlmZWN5Y2xlQnJpZGdlUGx1Z2luKTtcbiJdfQ==
|
|
153
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJjZXB0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW50ZXJjZXB0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBR0gsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQThDLE1BQU0sb0JBQW9CLENBQUM7QUFDbEcsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBRzdDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7QUF1RnpDLG1GQUFtRjtBQUNuRixNQUFNLGlCQUFpQixHQUFHLE1BQU0sQ0FBQztBQUVqQyw2RUFBNkU7QUFDN0UsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFVLENBQUM7QUFDbEUsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7QUFDakQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsRUFBYyxDQUFDO0FBQy9DLElBQUksbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0FBQ2hDLElBQUksbUJBQW1CLEdBQUcsS0FBSyxDQUFDO0FBRWhDLFNBQVMsZUFBZSxDQUFDLElBQVk7SUFDbkMsSUFBSSxtQkFBbUI7UUFBRSxPQUFPO0lBQ2hDLG1CQUFtQixHQUFHLElBQUksQ0FBQztJQUMzQixLQUFLLE1BQU0sT0FBTyxJQUFJLGdCQUFnQjtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ2xELGdCQUFnQixDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3pCLEtBQUssTUFBTSxLQUFLLElBQUksYUFBYSxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNO1lBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBQ0QsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RCLFVB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QzNCLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFDdEUsQ0FBQztJQUNILENBQUM7O0FBR0gsOERBQThEO0FBQzlELE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxRQUFRLENBQUMscUJBQXFCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogVGhlIGBjcmVhdGVBcHBgIElOVEVSQ0VQVE9SIGNvbnRleHQ6IGFuIGluLXByb2Nlc3MgaGFuZGxlIGFuIGFwcCBoYW5kcyB0b1xuICogYWRkLW9ucyAodGhlIHR1bm5lbCwgY2hpZWZseSkgc28gdGhleSBjYW4gcmVhZCB0aGUgZW52IGF1dG8tY29uZmlndXJhdGlvblxuICogY29tcHV0ZWQsIGhvb2sgQXBwS2l0J3MgbGlmZWN5Y2xlLCBhbmQgc3VwZXJ2aXNlIHNpYmxpbmcgY2hpbGQgcHJvY2Vzc2VzIGFzIG9uZVxuICogdW5pdCAtIGNvbmN1cnJlbnRseS1zdHlsZSwgd2hlcmUgYW55IGRlYXRoIHRha2VzIHRoZSB3aG9sZSBzZXQgZG93bi5cbiAqXG4gKiBBbiBpbnRlcmNlcHRvciBpcyBhIHBsYWluIGZ1bmN0aW9uIGAoY3R4KSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPmAgcGFzc2VkIHRvXG4gKiBgYXBwa2l0LmNyZWF0ZUFwcGAncyBgaW50ZXJjZXB0b3JgIG9wdGlvbiAoXCJvbmUgb3IgbWFueVwiKS4gYGFwcGtpdC5jcmVhdGVBcHBgXG4gKiBydW5zIGVhY2ggb25lIEFGVEVSIGF1dG8tY29uZmlndXJhdGlvbiBoYXMgcG9wdWxhdGVkIGBwcm9jZXNzLmVudmAgYnV0IGFzIHBhcnRcbiAqIG9mIGJvb3RpbmcgdGhlIGFwcCwgc28gYW4gaW50ZXJjZXB0b3Igc2VlcyB0aGUgcmVzb2x2ZWQgY29ubmVjdGlvbiBhbmQgY2FuIGJpbmRcbiAqIHByb2Nlc3NlcyBiZWZvcmUgb3IgZHVyaW5nIHNldHVwLlxuICpcbiAqIFRoZSBuYW1lcyBoZXJlIG1pcnJvciBBcHBLaXQncyBvd24gdm9jYWJ1bGFyeSByYXRoZXIgdGhhbiBpbnZlbnRpbmcgcGFyYWxsZWxcbiAqIG9uZXM6IHtAbGluayBMaWZlY3ljbGVFdmVudH0gYW5kIHtAbGluayBJbnRlcmNlcHRvckNvbnRleHQub25MaWZlY3ljbGV9IGFyZSB0aGVcbiAqIGV4YWN0IHNoYXBlIG9mIGBQbHVnaW5Db250ZXh0Lm9uTGlmZWN5Y2xlYCAoYHNldHVwOmNvbXBsZXRlYCAvIGBzZXJ2ZXI6cmVhZHlgIC9cbiAqIGBzaHV0ZG93bmApLiBUaGUgYnJpZGdlIHRoYXQgbWFrZXMgdGhhdCBob29rIHJlYWNoYWJsZSBmcm9tIE9VVFNJREUgYSBwbHVnaW4gLVxuICogd2hlcmUgaW50ZXJjZXB0b3JzIHJ1biAtIGlzIHtAbGluayBsaWZlY3ljbGVCcmlkZ2V9LCBhIHRpbnkgaW50ZXJuYWwgcGx1Z2luXG4gKiBgYXBwa2l0LmNyZWF0ZUFwcGAgaW5qZWN0cyB0byBjYXB0dXJlIGB0aGlzLmNvbnRleHRgIGFuZCByZWxheSBpdHMgZXZlbnRzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENoaWxkUHJvY2VzcyB9IGZyb20gXCJub2RlOmNoaWxkX3Byb2Nlc3NcIjtcbmltcG9ydCB7IFBsdWdpbiwgdG9QbHVnaW4sIHR5cGUgQmFzZVBsdWdpbkNvbmZpZywgdHlwZSBQbHVnaW5NYW5pZmVzdCB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGxvZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQgdHlwZSB7IExha2ViYXNlQ29ubmVjdGlvbiB9IGZyb20gXCIuL2xha2ViYXNlLXJlc29sdmVyLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJpbnRlcmNlcHRvclwiKTtcblxuLyoqXG4gKiBBcHBLaXQncyBwbHVnaW4tbGlmZWN5Y2xlIGV2ZW50cywgdmVyYmF0aW0gZnJvbSBgUGx1Z2luQ29udGV4dGBcbiAqIChgbm9kZV9tb2R1bGVzL0BkYXRhYnJpY2tzL2FwcGtpdC8uLi4vY29yZS9wbHVnaW4tY29udGV4dC5kLnRzYCkuIFJlLWRlY2xhcmVkXG4gKiBzdHJ1Y3R1cmFsbHkgcmF0aGVyIHRoYW4gaW1wb3J0ZWQgYmVjYXVzZSBgUGx1Z2luQ29udGV4dGAgaXMgbm90IGluIHRoZVxuICogcGFja2FnZSdzIGBleHBvcnRzYCBtYXAgKHRoZSBzYW1lIHJlYXNvbiB7QGxpbmsgUGx1Z2luQ29udGV4dExpa2V9IGV4aXN0cyBpblxuICogYC4vcGx1Z2luYCkuXG4gKlxuICogLSBgc2V0dXA6Y29tcGxldGVgIC0gZXZlcnkgcGx1Z2luJ3MgYHNldHVwKClgIGhhcyByZXNvbHZlZC5cbiAqIC0gYHNlcnZlcjpyZWFkeWAgLSB0aGUgYHNlcnZlcigpYCBwbHVnaW4gaXMgbGlzdGVuaW5nIChuZXZlciBmaXJlcyBmb3IgYVxuICogICBzZXJ2ZXJsZXNzIGFwcCwgZS5nLiB0aGUgdHVubmVsIGdhdGUpLlxuICogLSBgc2h1dGRvd25gIC0gdGhlIGFwcCBpcyB0ZWFyaW5nIGRvd24uXG4gKi9cbmV4cG9ydCB0eXBlIExpZmVjeWNsZUV2ZW50ID0gXCJzZXR1cDpjb21wbGV0ZVwiIHwgXCJzZXJ2ZXI6cmVhZHlcIiB8IFwic2h1dGRvd25cIjtcblxuLyoqIEEgbGlmZWN5Y2xlIHN1YnNjcmliZXIuIEVycm9ycyBhcmUgbG9nZ2VkLCBub3QgcHJvcGFnYXRlZCAobWF0Y2hlcyBBcHBLaXQpLiAqL1xuZXhwb3J0IHR5cGUgTGlmZWN5Y2xlSGFuZGxlciA9ICgpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuXG4vKipcbiAqIFRoZSBlbnYgYXV0by1jb25maWd1cmF0aW9uIHJlc29sdmVkIGJlZm9yZSBib290LCBleHBvc2VkIHRvIGludGVyY2VwdG9ycyBzb1xuICogdGhleSByZWFkIENPTVBVVEVEIHZhbHVlcyBpbnN0ZWFkIG9mIHJlLXJlYWRpbmcgYHByb2Nlc3MuZW52YCB0aGVtc2VsdmVzLlxuICpcbiAqIGBsYWtlYmFzZWAgaXMgdGhlIHJlc29sdmVkIFBvc3RncmVzIGNvbm5lY3Rpb24gd2hlbiBMYWtlYmFzZSBhdXRvLWNvbmZpZyByYW5cbiAqIChzZWUgYGFwcGtpdC5hdXRvQ29uZmlndXJlYCksIGVsc2UgYHVuZGVmaW5lZGAuIGBkYXRhYnJpY2tzSG9zdGAgaXMgdGhlXG4gKiB3b3Jrc3BhY2UgaG9zdCBhcyByZXNvbHZlZCBpbnRvIHRoZSBlbnZpcm9ubWVudCAoYERBVEFCUklDS1NfSE9TVGApLCB3aGljaCB0aGVcbiAqIHR1bm5lbCBpbnRlcmNlcHRvciBib3RoIHJlYWRzIGFuZCwgd2hlbiBpdCBtdXN0LCBzZXRzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVkQXBwRW52IHtcbiAgLyoqIFJlc29sdmVkIExha2ViYXNlIGNvbm5lY3Rpb24sIHdoZW4gYXV0by1jb25maWcgcmVzb2x2ZWQgb25lLiAqL1xuICByZWFkb25seSBsYWtlYmFzZT86IExha2ViYXNlQ29ubmVjdGlvbjtcbiAgLyoqIFJlc29sdmVkIERhdGFicmlja3Mgd29ya3NwYWNlIGhvc3QgKGBEQVRBQlJJQ0tTX0hPU1RgKSwgd2hlbiBrbm93bi4gKi9cbiAgcmVhZG9ubHkgZGF0YWJyaWNrc0hvc3Q/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBwcm9jZXNzIHtAbGluayBJbnRlcmNlcHRvckNvbnRleHQuYmluZFByb2Nlc3N9IGNhbiBzdXBlcnZpc2UuIEEgYmFyZVxuICogYG5vZGU6Y2hpbGRfcHJvY2Vzc2AgYENoaWxkUHJvY2Vzc2AgKGUuZy4gcG9ydHIpIHNhdGlzZmllcyB0aGlzLCBhbmQgc28gZG9lc1xuICogYEBkYngtdG9vbHMvY29yZWAncyBgc3Bhd24oKWAgcmVzdWx0IChhIGBDaGlsZFByb2Nlc3NSZXN1bHRgIElTIGFcbiAqIGBDaGlsZFByb2Nlc3NgKSAtIG9uZSBjb2RlIHBhdGggaGFuZGxlcyBib3RoLlxuICovXG5leHBvcnQgdHlwZSBCaW5kYWJsZVByb2Nlc3MgPSBQaWNrPENoaWxkUHJvY2VzcywgXCJwaWRcIiB8IFwia2lsbFwiIHwgXCJraWxsZWRcIiB8IFwib25jZVwiPjtcblxuLyoqXG4gKiBUaGUgaGFuZGxlIHBhc3NlZCB0byBlYWNoIGludGVyY2VwdG9yLlxuICpcbiAqIEBleGFtcGxlXG4gKiBpbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbiAqXG4gKiBhd2FpdCBhcHBraXQuY3JlYXRlQXBwKHtcbiAqICAgcGx1Z2luczogW3NlcnZlcigpXSxcbiAqICAgaW50ZXJjZXB0b3I6IChjdHgpID0+IHtcbiAqICAgICBjb25zdCBwb3J0ciA9IHNwYXduUG9ydHIoY3R4LmVudi5kYXRhYnJpY2tzSG9zdCk7XG4gKiAgICAgY3R4LmJpbmRQcm9jZXNzKHBvcnRyKTsgICAgICAgICAgICAvLyBhcHAgPC0+IHBvcnRyIGxpdmUvZGllIHRvZ2V0aGVyXG4gKiAgICAgY3R4Lm9uTGlmZWN5Y2xlKFwic2h1dGRvd25cIiwgKCkgPT4gcG9ydHIua2lsbChcIlNJR1RFUk1cIikpO1xuICogICB9LFxuICogfSk7XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJjZXB0b3JDb250ZXh0IHtcbiAgLyoqIFRoZSBlbnYgYXV0by1jb25maWd1cmF0aW9uIGNvbXB1dGVkIGJlZm9yZSBib290LiAqL1xuICByZWFkb25seSBlbnY6IFJlc29sdmVkQXBwRW52O1xuICAvKipcbiAgICogU3Vic2NyaWJlIHRvIGFuIEFwcEtpdCBsaWZlY3ljbGUgZXZlbnQuIE1pcnJvcnMgYFBsdWdpbkNvbnRleHQub25MaWZlY3ljbGVgO1xuICAgKiB0aGUgaW5qZWN0ZWQge0BsaW5rIGxpZmVjeWNsZUJyaWRnZX0gcmVsYXlzIHRoZSByZWFsIGV2ZW50cyBoZXJlIG9uY2UgdGhlIGFwcFxuICAgKiBib290cy4gQSBoYW5kbGVyIHJlZ2lzdGVyZWQgZm9yIGFuIGV2ZW50IHRoYXQgYWxyZWFkeSBmaXJlZCBpcyBOT1QgY2FsbGVkXG4gICAqIHJldHJvYWN0aXZlbHkgKHNhbWUgc2VtYW50aWNzIGFzIEFwcEtpdCkuXG4gICAqL1xuICBvbkxpZmVjeWNsZShldmVudDogTGlmZWN5Y2xlRXZlbnQsIGZuOiBMaWZlY3ljbGVIYW5kbGVyKTogdm9pZDtcbiAgLyoqIFJlZ2lzdGVyIHN5bmNocm9ub3VzIGNsZWFudXAgdGhhdCBydW5zIGJlZm9yZSBhbnkgYm91bmQgcHJvY2VzcyBpcyBraWxsZWQuICovXG4gIG9uVGVhcmRvd24oZm46ICgpID0+IHZvaWQpOiB2b2lkO1xuICAvKipcbiAgICogQnJvYWRjYXN0IGEgdGVybWluYXRpb24gc2lnbmFsIGZyb20gdGhlIG1haW4gYXBwIHRvIGV2ZXJ5IGJvdW5kIHByb2Nlc3MuXG4gICAqIENhbGxlZCBhdXRvbWF0aWNhbGx5IHdoZW4gdGhpcyBwcm9jZXNzIHJlY2VpdmVzIGBTSUdJTlRgL2BTSUdURVJNYC9gU0lHSFVQYDtcbiAgICogZXhwb3NlZCBzbyBhbiBpbnRlcmNlcHRvciBjYW4gdHJpZ2dlciB0ZWFyZG93biBpdHNlbGYuXG4gICAqL1xuICBicm9hZGNhc3RTaWduYWwoc2lnbmFsOiBOb2RlSlMuU2lnbmFscyk6IHZvaWQ7XG4gIC8qKlxuICAgKiBTdXBlcnZpc2UgYSBjaGlsZCBwcm9jZXNzIGFsb25nc2lkZSB0aGUgYXBwLCBjb25jdXJyZW50bHktc3R5bGU6IHNpZ25hbHMgcGFzc1xuICAgKiB0aHJvdWdoLCBhbmQgaWYgRUlUSEVSIHRoZSBjaGlsZCBvciB0aGUgYXBwIGRpZXMgdGhlIHdob2xlIHNldCBjb21lcyBkb3duLlxuICAgKiBTYWZlIHRvIGNhbGwgZm9yIHNldmVyYWwgY2hpbGRyZW47IHRlYXJkb3duIGlzIGlkZW1wb3RlbnQuXG4gICAqL1xuICBiaW5kUHJvY2VzcyhjaGlsZDogQmluZGFibGVQcm9jZXNzKTogdm9pZDtcbn1cblxuLyoqIEEgc2luZ2xlIGludGVyY2VwdG9yLCBvciBzZXZlcmFsLiBUaGUgYGNyZWF0ZUFwcGAgYGludGVyY2VwdG9yPzpgIG9wdGlvbi4gKi9cbmV4cG9ydCB0eXBlIEludGVyY2VwdG9yID0gKGN0eDogSW50ZXJjZXB0b3JDb250ZXh0KSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcblxuLyoqIEhvdyBsb25nIGJvdW5kIGNoaWxkcmVuIGdldCB0byBleGl0IG9uIGBTSUdURVJNYCBiZWZvcmUgdGhlIGFwcCBmb3JjZS1leGl0cy4gKi9cbmNvbnN0IFRFQVJET1dOX0dSQUNFX01TID0gMTBfMDAwO1xuXG4vKiogVGhlIHNpZ25hbHMgdGhhdCB0cmlnZ2VyIHRlYXJkb3duIHdoZW4gdGhlIE1BSU4gcHJvY2VzcyByZWNlaXZlcyB0aGVtLiAqL1xuY29uc3QgVEVBUkRPV05fU0lHTkFMUyA9IFtcIlNJR0lOVFwiLCBcIlNJR1RFUk1cIiwgXCJTSUdIVVBcIl0gYXMgY29uc3Q7XG5jb25zdCBib3VuZENoaWxkcmVuID0gbmV3IFNldDxCaW5kYWJsZVByb2Nlc3M+KCk7XG5jb25zdCB0ZWFyZG93bkhhbmRsZXJzID0gbmV3IFNldDwoKSA9PiB2b2lkPigpO1xubGV0IHByb2Nlc3NTaHV0dGluZ0Rvd24gPSBmYWxzZTtcbmxldCBwcm9jZXNzU2lnbmFsc0JvdW5kID0gZmFsc2U7XG5cbmZ1bmN0aW9uIHRlYXJkb3duUHJvY2Vzcyhjb2RlOiBudW1iZXIpOiB2b2lkIHtcbiAgaWYgKHByb2Nlc3NTaHV0dGluZ0Rvd24pIHJldHVybjtcbiAgcHJvY2Vzc1NodXR0aW5nRG93biA9IHRydWU7XG4gIGZvciAoY29uc3QgaGFuZGxlciBvZiB0ZWFyZG93bkhhbmRsZXJzKSBoYW5kbGVyKCk7XG4gIHRlYXJkb3duSGFuZGxlcnMuY2xlYXIoKTtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBib3VuZENoaWxkcmVuKSB7XG4gICAgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoXCJTSUdURVJNXCIpO1xuICB9XG4gIGJvdW5kQ2hpbGRyZW4uY2xlYXIoKTtcbiAgc2V0VGltZW91dCgoKSA9PiBwcm9jZXNzLmV4aXQoY29kZSksIFRFQVJET1dOX0dSQUNFX01TKS51bnJlZigpO1xufVxuXG5mdW5jdGlvbiBicm9hZGNhc3RQcm9jZXNzU2lnbmFsKHNpZ25hbDogTm9kZUpTLlNpZ25hbHMpOiB2b2lkIHtcbiAgZm9yIChjb25zdCBjaGlsZCBvZiBib3VuZENoaWxkcmVuKSB7XG4gICAgaWYgKCFjaGlsZC5raWxsZWQpIGNoaWxkLmtpbGwoc2lnbmFsKTtcbiAgfVxuICB0ZWFyZG93blByb2Nlc3MoMCk7XG59XG5cbmZ1bmN0aW9uIGJpbmRQcm9jZXNzU2lnbmFscygpOiB2b2lkIHtcbiAgaWYgKHByb2Nlc3NTaWduYWxzQm91bmQpIHJldHVybjtcbiAgcHJvY2Vzc1NpZ25hbHNCb3VuZCA9IHRydWU7XG4gIGZvciAoY29uc3Qgc2lnbmFsIG9mIFRFQVJET1dOX1NJR05BTFMpIHtcbiAgICBwcm9jZXNzLm9uKHNpZ25hbCwgKCkgPT4gYnJvYWRjYXN0UHJvY2Vzc1NpZ25hbChzaWduYWwpKTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSBtdXRhYmxlIG1hY2hpbmVyeSBiZWhpbmQgYW4ge0BsaW5rIEludGVyY2VwdG9yQ29udGV4dH0uIFNwbGl0IG91dCBzb1xuICoge0BsaW5rIGNyZWF0ZUludGVyY2VwdG9yQ29udGV4dH0gY2FuIGhhbmQgdGhlIHB1YmxpYyBjb250ZXh0IHRvIGludGVyY2VwdG9yc1xuICogd2hpbGUgYGFwcGtpdC5jcmVhdGVBcHBgIHJldGFpbnMgdGhlIGBlbWl0TGlmZWN5Y2xlYCBzaWRlLWNoYW5uZWwgdGhlIGJyaWRnZSBkcml2ZXMuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJjZXB0b3JSdW50aW1lIHtcbiAgLyoqIFRoZSBjb250ZXh0IGhhbmRlZCB0byBlYWNoIGludGVyY2VwdG9yLiAqL1xuICByZWFkb25seSBjb250ZXh0OiBJbnRlcmNlcHRvckNvbnRleHQ7XG4gIC8qKiBGaXJlIGEgbGlmZWN5Y2xlIGV2ZW50IHRvIGV2ZXJ5IHN1YnNjcmliZXIgKGNhbGxlZCBieSB7QGxpbmsgbGlmZWN5Y2xlQnJpZGdlfSkuICovXG4gIGVtaXRMaWZlY3ljbGUoZXZlbnQ6IExpZmVjeWNsZUV2ZW50KTogUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqXG4gKiBCdWlsZCBhbiB7QGxpbmsgSW50ZXJjZXB0b3JDb250ZXh0fSArIGl0cyB7QGxpbmsgSW50ZXJjZXB0b3JSdW50aW1lfS5cbiAqXG4gKiBUZWFyZG93biBpcyB0aGUgZ2VuZXJhbGl6ZWQgYHN1cGVydmlzZUV4aXRgOiB0aGUgZmlyc3QgY2hpbGQgZXhpdCBvciBtYWluLXByb2Nlc3NcbiAqIHRlcm1pbmF0aW9uIHNpZ25hbCBmbGlwcyBhIG9uZS1zaG90IGd1YXJkLCBgU0lHVEVSTWBzIHRoZSBvdGhlciBib3VuZCBjaGlsZHJlbixcbiAqIHRoZW4gYHByb2Nlc3MuZXhpdGBzIGFmdGVyIHtAbGluayBURUFSRE9XTl9HUkFDRV9NU30gKGFuIGB1bnJlZmAnZCB0aW1lciwgc28gaXRcbiAqIG5ldmVyIGl0c2VsZiBob2xkcyB0aGUgbG9vcCBvcGVuKS4gVGhlIHByb2Nlc3Mtc2lnbmFsIGxpc3RlbmVycyBhcmUgaW5zdGFsbGVkXG4gKiBsYXppbHkgb24gdGhlIGZpcnN0IGBiaW5kUHJvY2Vzc2Agc28gYW4gYXBwIHRoYXQgYmluZHMgbm90aGluZyBpcyB1bnRvdWNoZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVJbnRlcmNlcHRvckNvbnRleHQoZW52OiBSZXNvbHZlZEFwcEVudik6IEludGVyY2VwdG9yUnVudGltZSB7XG4gIGNvbnN0IGhhbmRsZXJzID0gbmV3IE1hcDxMaWZlY3ljbGVFdmVudCwgTGlmZWN5Y2xlSGFuZGxlcltdPigpO1xuICBpZiAocHJvY2Vzc1NodXR0aW5nRG93biAmJiBib3VuZENoaWxkcmVuLnNpemUgPT09IDApIHByb2Nlc3NTaHV0dGluZ0Rvd24gPSBmYWxzZTtcbiAgaWYgKFxuICAgIHByb2Nlc3NTaWduYWxzQm91bmQgJiZcbiAgICBURUFSRE9XTl9TSUdOQUxTLmV2ZXJ5KChzaWduYWwpID0+IHByb2Nlc3MubGlzdGVuZXJDb3VudChzaWduYWwpID09PSAwKVxuICApIHtcbiAgICBwcm9jZXNzU2lnbmFsc0JvdW5kID0gZmFsc2U7XG4gIH1cblxuICBjb25zdCBiaW5kUHJvY2VzcyA9IChjaGlsZDogQmluZGFibGVQcm9jZXNzKTogdm9pZCA9PiB7XG4gICAgYmluZFByb2Nlc3NTaWduYWxzKCk7XG4gICAgYm91bmRDaGlsZHJlbi5hZGQoY2hpbGQpO1xuICAgIGNoaWxkLm9uY2UoXCJleGl0XCIsIChjb2RlKSA9PiB7XG4gICAgICBsb2dnZXIud2FybihcImJvdW5kIHByb2Nlc3MgZXhpdGVkOyB0ZWFyaW5nIGRvd24gdGhlIGFwcFwiLCB7IGNvZGUgfSk7XG4gICAgICB0ZWFyZG93blByb2Nlc3ModHlwZW9mIGNvZGUgPT09IFwibnVtYmVyXCIgPyBjb2RlIDogMSk7XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3Qgb25MaWZlY3ljbGUgPSAoZXZlbnQ6IExpZmVjeWNsZUV2ZW50LCBmbjogTGlmZWN5Y2xlSGFuZGxlcik6IHZvaWQgPT4ge1xuICAgIGNvbnN0IGxpc3QgPSBoYW5kbGVycy5nZXQoZXZlbnQpO1xuICAgIGlmIChsaXN0KSBsaXN0LnB1c2goZm4pO1xuICAgIGVsc2UgaGFuZGxlcnMuc2V0KGV2ZW50LCBbZm5dKTtcbiAgfTtcblxuICBjb25zdCBlbWl0TGlmZWN5Y2xlID0gYXN5bmMgKGV2ZW50OiBMaWZlY3ljbGVFdmVudCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgIGNvbnN0IGxpc3QgPSBoYW5kbGVycy5nZXQoZXZlbnQpO1xuICAgIGlmICghbGlzdCkgcmV0dXJuO1xuICAgIGZvciAoY29uc3QgZm4gb2YgbGlzdCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgZm4oKTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIE1hdGNoIEFwcEtpdDogYSBmYWlsaW5nIGxpZmVjeWNsZSBoYW5kbGVyIGlzIGxvZ2dlZCwgbmV2ZXIgZmF0YWwsIGFuZFxuICAgICAgICAvLyBuZXZlciBibG9ja3MgaXRzIHNpYmxpbmdzLlxuICAgICAgICBsb2dnZXIud2FybihcImxpZmVjeWNsZSBoYW5kbGVyIGZhaWxlZFwiLCB7IGV2ZW50LCBlcnJvciB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgY29uc3QgY29udGV4dDogSW50ZXJjZXB0b3JDb250ZXh0ID0ge1xuICAgIGVudixcbiAgICBvbkxpZmVjeWNsZSxcbiAgICBvblRlYXJkb3duOiAoZm4pID0+IHRlYXJkb3duSGFuZGxlcnMuYWRkKGZuKSxcbiAgICBicm9hZGNhc3RTaWduYWw6IGJyb2FkY2FzdFByb2Nlc3NTaWduYWwsXG4gICAgYmluZFByb2Nlc3MsXG4gIH07XG5cbiAgcmV0dXJuIHsgY29udGV4dCwgZW1pdExpZmVjeWNsZSB9O1xufVxuXG4vKiogQ29uZmlnIGZvciB7QGxpbmsgTGlmZWN5Y2xlQnJpZGdlUGx1Z2lufTogdGhlIHNpbmsgaXRzIGNhcHR1cmVkIGV2ZW50cyBmbG93IHRvLiAqL1xuaW50ZXJmYWNlIExpZmVjeWNsZUJyaWRnZUNvbmZpZyBleHRlbmRzIEJhc2VQbHVnaW5Db25maWcge1xuICAvKiogVGhlIHJ1bnRpbWUgd2hvc2UgYGVtaXRMaWZlY3ljbGVgIHJlY2VpdmVzIHRoZSByZWFsIEFwcEtpdCBldmVudHMuICovXG4gIHJ1bnRpbWU/OiBJbnRlcmNlcHRvclJ1bnRpbWU7XG59XG5cbi8qKlxuICogU3RydWN0dXJhbCBzaGFwZSBvZiB0aGUgYFBsdWdpbkNvbnRleHQub25MaWZlY3ljbGVgIHdlIGJyaWRnZS4gTWlycm9ycyBvbmx5IHRoZVxuICogb25lIG1ldGhvZCB3ZSB0b3VjaCAobGlrZSB7QGxpbmsgUGx1Z2luQ29udGV4dExpa2V9IGluIGAuL3BsdWdpbmApLCBzaW5jZVxuICogQXBwS2l0J3MgYFBsdWdpbkNvbnRleHRgIGlzIG5vdCBpbXBvcnRhYmxlIGZyb20gdGhlIHBhY2thZ2UncyBgZXhwb3J0c2AuXG4gKi9cbmludGVyZmFjZSBMaWZlY3ljbGVDb250ZXh0TGlrZSB7XG4gIG9uTGlmZWN5Y2xlKGV2ZW50OiBMaWZlY3ljbGVFdmVudCwgZm46IExpZmVjeWNsZUhhbmRsZXIpOiB2b2lkO1xufVxuXG5mdW5jdGlvbiBoYXNPbkxpZmVjeWNsZShjb250ZXh0OiB1bmtub3duKTogY29udGV4dCBpcyBMaWZlY3ljbGVDb250ZXh0TGlrZSB7XG4gIHJldHVybiB0eXBlb2YgKGNvbnRleHQgYXMgTGlmZWN5Y2xlQ29udGV4dExpa2UgfCB1bmRlZmluZWQpPy5vbkxpZmVjeWNsZSA9PT0gXCJmdW5jdGlvblwiO1xufVxuXG4vKipcbiAqIFRoZSBpbnRlcm5hbCBwbHVnaW4gYGFwcGtpdC5jcmVhdGVBcHBgIGluamVjdHMgdG8gbWFrZSBBcHBLaXQncyBsaWZlY3ljbGVcbiAqIHJlYWNoYWJsZSBmcm9tIGludGVyY2VwdG9yIGNvZGUuIE9uIGBzZXR1cCgpYCBpdCByZWFkcyBpdHMgb3duIGB0aGlzLmNvbnRleHRgXG4gKiAodGhlIHJlYWwgYFBsdWdpbkNvbnRleHRgKSBhbmQgZm9yd2FyZHMgZWFjaCB7QGxpbmsgTGlmZWN5Y2xlRXZlbnR9IHRvIHRoZVxuICogaW50ZXJjZXB0b3IgcnVudGltZSwgc28gYGN0eC5vbkxpZmVjeWNsZSguLi4pYCBoYW5kbGVycyBmaXJlIG9uIHRoZSBnZW51aW5lXG4gKiBldmVudHMuIEl0IG93bnMgbm8gcm91dGVzLCBjb25maWcgc3VyZmFjZSwgb3IgZXhwb3J0cy5cbiAqL1xuZXhwb3J0IGNsYXNzIExpZmVjeWNsZUJyaWRnZVBsdWdpbiBleHRlbmRzIFBsdWdpbjxMaWZlY3ljbGVCcmlkZ2VDb25maWc+IHtcbiAgc3RhdGljIG1hbmlmZXN0ID0ge1xuICAgIG5hbWU6IFwiZGJ4VG9vbHNMaWZlY3ljbGVCcmlkZ2VcIixcbiAgICBkaXNwbGF5TmFtZTogXCJMaWZlY3ljbGUgQnJpZGdlXCIsXG4gICAgZGVzY3JpcHRpb246IFwiUmVsYXlzIEFwcEtpdCBsaWZlY3ljbGUgZXZlbnRzIHRvIHRoZSBjcmVhdGVBcHAgaW50ZXJjZXB0b3IgY29udGV4dC5cIixcbiAgICBzdGFiaWxpdHk6IFwiYmV0YVwiLFxuICAgIGhpZGRlbjogdHJ1ZSxcbiAgICByZXNvdXJjZXM6IHsgcmVxdWlyZWQ6IFtdLCBvcHRpb25hbDogW10gfSxcbiAgfSBzYXRpc2ZpZXMgUGx1Z2luTWFuaWZlc3Q8XCJkYnhUb29sc0xpZmVjeWNsZUJyaWRnZVwiPjtcblxuICBvdmVycmlkZSBhc3luYyBzZXR1cCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBydW50aW1lID0gdGhpcy5jb25maWcucnVudGltZTtcbiAgICBpZiAoIXJ1bnRpbWUpIHJldHVybjtcbiAgICBpZiAoIWhhc09uTGlmZWN5Y2xlKHRoaXMuY29udGV4dCkpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcIm5vIFBsdWdpbkNvbnRleHQub25MaWZlY3ljbGUgdG8gYnJpZGdlOyBpbnRlcmNlcHRvciBsaWZlY3ljbGUgZXZlbnRzIGluZXJ0XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBldmVudHM6IExpZmVjeWNsZUV2ZW50W10gPSBbXCJzZXR1cDpjb21wbGV0ZVwiLCBcInNlcnZlcjpyZWFkeVwiLCBcInNodXRkb3duXCJdO1xuICAgIGZvciAoY29uc3QgZXZlbnQgb2YgZXZlbnRzKSB7XG4gICAgICB0aGlzLmNvbnRleHQub25MaWZlY3ljbGUoZXZlbnQsICgpID0+IHJ1bnRpbWUuZW1pdExpZmVjeWNsZShldmVudCkpO1xuICAgIH1cbiAgfVxufVxuXG4vKiogRmFjdG9yeSBmb3IgdGhlIGluamVjdGVkIHtAbGluayBMaWZlY3ljbGVCcmlkZ2VQbHVnaW59LiAqL1xuZXhwb3J0IGNvbnN0IGxpZmVjeWNsZUJyaWRnZSA9IHRvUGx1Z2luKExpZmVjeWNsZUJyaWRnZVBsdWdpbik7XG4iXX0=
|
package/package.json
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@databricks/appkit": "^0.60.0",
|
|
22
|
-
"@dbx-tools/test-polyglot": "0.6.
|
|
22
|
+
"@dbx-tools/test-polyglot": "0.6.113",
|
|
23
23
|
"@types/bun": "^1.3.14",
|
|
24
24
|
"@types/node": "^24.6.0",
|
|
25
25
|
"typescript": "^5.9.3"
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@databricks/sdk-experimental": "^0.17.0",
|
|
32
|
-
"@dbx-tools/core": "0.6.
|
|
33
|
-
"@dbx-tools/shared-core": "0.6.
|
|
32
|
+
"@dbx-tools/core": "0.6.113",
|
|
33
|
+
"@dbx-tools/shared-core": "0.6.113",
|
|
34
34
|
"zod": "4.3.6"
|
|
35
35
|
},
|
|
36
36
|
"main": "./lib/index.js",
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"./package.json": "./package.json"
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
-
"version": "0.6.
|
|
50
|
+
"version": "0.6.113",
|
|
51
51
|
"types": "./lib/index.d.ts",
|
|
52
52
|
"type": "module",
|
|
53
53
|
"exports": {
|
package/src/interceptor.ts
CHANGED
|
@@ -93,6 +93,8 @@ export interface InterceptorContext {
|
|
|
93
93
|
* retroactively (same semantics as AppKit).
|
|
94
94
|
*/
|
|
95
95
|
onLifecycle(event: LifecycleEvent, fn: LifecycleHandler): void;
|
|
96
|
+
/** Register synchronous cleanup that runs before any bound process is killed. */
|
|
97
|
+
onTeardown(fn: () => void): void;
|
|
96
98
|
/**
|
|
97
99
|
* Broadcast a termination signal from the main app to every bound process.
|
|
98
100
|
* Called automatically when this process receives `SIGINT`/`SIGTERM`/`SIGHUP`;
|
|
@@ -111,10 +113,41 @@ export interface InterceptorContext {
|
|
|
111
113
|
export type Interceptor = (ctx: InterceptorContext) => void | Promise<void>;
|
|
112
114
|
|
|
113
115
|
/** How long bound children get to exit on `SIGTERM` before the app force-exits. */
|
|
114
|
-
const TEARDOWN_GRACE_MS =
|
|
116
|
+
const TEARDOWN_GRACE_MS = 10_000;
|
|
115
117
|
|
|
116
118
|
/** The signals that trigger teardown when the MAIN process receives them. */
|
|
117
119
|
const TEARDOWN_SIGNALS = ["SIGINT", "SIGTERM", "SIGHUP"] as const;
|
|
120
|
+
const boundChildren = new Set<BindableProcess>();
|
|
121
|
+
const teardownHandlers = new Set<() => void>();
|
|
122
|
+
let processShuttingDown = false;
|
|
123
|
+
let processSignalsBound = false;
|
|
124
|
+
|
|
125
|
+
function teardownProcess(code: number): void {
|
|
126
|
+
if (processShuttingDown) return;
|
|
127
|
+
processShuttingDown = true;
|
|
128
|
+
for (const handler of teardownHandlers) handler();
|
|
129
|
+
teardownHandlers.clear();
|
|
130
|
+
for (const child of boundChildren) {
|
|
131
|
+
if (!child.killed) child.kill("SIGTERM");
|
|
132
|
+
}
|
|
133
|
+
boundChildren.clear();
|
|
134
|
+
setTimeout(() => process.exit(code), TEARDOWN_GRACE_MS).unref();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function broadcastProcessSignal(signal: NodeJS.Signals): void {
|
|
138
|
+
for (const child of boundChildren) {
|
|
139
|
+
if (!child.killed) child.kill(signal);
|
|
140
|
+
}
|
|
141
|
+
teardownProcess(0);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function bindProcessSignals(): void {
|
|
145
|
+
if (processSignalsBound) return;
|
|
146
|
+
processSignalsBound = true;
|
|
147
|
+
for (const signal of TEARDOWN_SIGNALS) {
|
|
148
|
+
process.on(signal, () => broadcastProcessSignal(signal));
|
|
149
|
+
}
|
|
150
|
+
}
|
|
118
151
|
|
|
119
152
|
/**
|
|
120
153
|
* The mutable machinery behind an {@link InterceptorContext}. Split out so
|
|
@@ -139,40 +172,20 @@ export interface InterceptorRuntime {
|
|
|
139
172
|
*/
|
|
140
173
|
export function createInterceptorContext(env: ResolvedAppEnv): InterceptorRuntime {
|
|
141
174
|
const handlers = new Map<LifecycleEvent, LifecycleHandler[]>();
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
for (const child of children) {
|
|
150
|
-
if (!child.killed) child.kill("SIGTERM");
|
|
151
|
-
}
|
|
152
|
-
setTimeout(() => process.exit(code), TEARDOWN_GRACE_MS).unref();
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
const broadcastSignal = (signal: NodeJS.Signals): void => {
|
|
156
|
-
for (const child of children) {
|
|
157
|
-
if (!child.killed) child.kill(signal);
|
|
158
|
-
}
|
|
159
|
-
teardown(0);
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
const bindProcessSignals = (): void => {
|
|
163
|
-
if (signalsBound) return;
|
|
164
|
-
signalsBound = true;
|
|
165
|
-
for (const signal of TEARDOWN_SIGNALS) {
|
|
166
|
-
process.on(signal, () => broadcastSignal(signal));
|
|
167
|
-
}
|
|
168
|
-
};
|
|
175
|
+
if (processShuttingDown && boundChildren.size === 0) processShuttingDown = false;
|
|
176
|
+
if (
|
|
177
|
+
processSignalsBound &&
|
|
178
|
+
TEARDOWN_SIGNALS.every((signal) => process.listenerCount(signal) === 0)
|
|
179
|
+
) {
|
|
180
|
+
processSignalsBound = false;
|
|
181
|
+
}
|
|
169
182
|
|
|
170
183
|
const bindProcess = (child: BindableProcess): void => {
|
|
171
184
|
bindProcessSignals();
|
|
172
|
-
|
|
185
|
+
boundChildren.add(child);
|
|
173
186
|
child.once("exit", (code) => {
|
|
174
187
|
logger.warn("bound process exited; tearing down the app", { code });
|
|
175
|
-
|
|
188
|
+
teardownProcess(typeof code === "number" ? code : 1);
|
|
176
189
|
});
|
|
177
190
|
};
|
|
178
191
|
|
|
@@ -199,7 +212,8 @@ export function createInterceptorContext(env: ResolvedAppEnv): InterceptorRuntim
|
|
|
199
212
|
const context: InterceptorContext = {
|
|
200
213
|
env,
|
|
201
214
|
onLifecycle,
|
|
202
|
-
|
|
215
|
+
onTeardown: (fn) => teardownHandlers.add(fn),
|
|
216
|
+
broadcastSignal: broadcastProcessSignal,
|
|
203
217
|
bindProcess,
|
|
204
218
|
};
|
|
205
219
|
|