@dbx-tools/appkit-mastra 0.6.69 → 0.6.71
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/lib/src/memory.d.ts +14 -1
- package/lib/src/memory.js +48 -9
- package/package.json +13 -13
- package/src/memory.ts +72 -16
package/lib/src/memory.d.ts
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
* **per-agent** namespacing via {@link agentStorageSchemaName} so
|
|
9
9
|
* conversation history stays isolated between agents in the same
|
|
10
10
|
* database. `PostgresStore` auto-creates the schema with
|
|
11
|
-
* `CREATE SCHEMA IF NOT EXISTS` on init.
|
|
11
|
+
* `CREATE SCHEMA IF NOT EXISTS` on init. A failed migration (common on
|
|
12
|
+
* Lakebase when the connecting role is not the table owner) is logged
|
|
13
|
+
* and skipped via {@link withSoftStorageInit} so existing tables keep
|
|
14
|
+
* serving instead of retrying DDL on every request.
|
|
12
15
|
* - **Memory** (semantic recall via `PgVector`): defaults to a single
|
|
13
16
|
* **shared** instance across every agent. Cross-agent recall on one
|
|
14
17
|
* index is almost always what users want; opt into per-agent recall
|
|
@@ -33,6 +36,16 @@ import { PostgresStore } from "@mastra/pg";
|
|
|
33
36
|
import { Pool, type PoolConfig } from "pg";
|
|
34
37
|
import type { MastraAgentDefinition } from "./agents.ts";
|
|
35
38
|
import type { MastraPluginConfig } from "./config.ts";
|
|
39
|
+
/**
|
|
40
|
+
* Soften {@link PostgresStore.init} so a failed migration (e.g. Lakebase
|
|
41
|
+
* `must be owner of table …` on `ALTER`) is logged once instead of rethrown
|
|
42
|
+
* on every storage call.
|
|
43
|
+
*
|
|
44
|
+
* Mastra's `augmentWithInit` retries init forever when it throws, so the
|
|
45
|
+
* only way to keep serving against an already-usable schema is to treat
|
|
46
|
+
* migration failure as success and mark the store initialized.
|
|
47
|
+
*/
|
|
48
|
+
export declare function withSoftStorageInit(store: PostgresStore): PostgresStore;
|
|
36
49
|
/**
|
|
37
50
|
* Build a dedicated **service-principal** Lakebase pool for Mastra
|
|
38
51
|
* memory from the lakebase plugin's resolved SP pg config.
|
package/lib/src/memory.js
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
* **per-agent** namespacing via {@link agentStorageSchemaName} so
|
|
9
9
|
* conversation history stays isolated between agents in the same
|
|
10
10
|
* database. `PostgresStore` auto-creates the schema with
|
|
11
|
-
* `CREATE SCHEMA IF NOT EXISTS` on init.
|
|
11
|
+
* `CREATE SCHEMA IF NOT EXISTS` on init. A failed migration (common on
|
|
12
|
+
* Lakebase when the connecting role is not the table owner) is logged
|
|
13
|
+
* and skipped via {@link withSoftStorageInit} so existing tables keep
|
|
14
|
+
* serving instead of retrying DDL on every request.
|
|
12
15
|
* - **Memory** (semantic recall via `PgVector`): defaults to a single
|
|
13
16
|
* **shared** instance across every agent. Cross-agent recall on one
|
|
14
17
|
* index is almost always what users want; opt into per-agent recall
|
|
@@ -29,7 +32,7 @@
|
|
|
29
32
|
* @module
|
|
30
33
|
*/
|
|
31
34
|
import { getUsernameWithApiLookup } from "@databricks/appkit";
|
|
32
|
-
import { hash, log } from "@dbx-tools/shared-core";
|
|
35
|
+
import { error, hash, log } from "@dbx-tools/shared-core";
|
|
33
36
|
import { fastembed } from "@mastra/fastembed";
|
|
34
37
|
import { Memory } from "@mastra/memory";
|
|
35
38
|
import { PgVector, PostgresStore } from "@mastra/pg";
|
|
@@ -37,6 +40,42 @@ import { Pool } from "pg";
|
|
|
37
40
|
import { agentStorageSchemaName } from "./storage-schema.js";
|
|
38
41
|
import { summaryModel, TITLE_INSTRUCTIONS } from "./summarize.js";
|
|
39
42
|
const logger = log.logger("mastra/memory");
|
|
43
|
+
/** Whether `LOG_LEVEL` is currently at or below debug. */
|
|
44
|
+
function isDebugEnabled() {
|
|
45
|
+
return log.isLevelEnabled("debug");
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Soften {@link PostgresStore.init} so a failed migration (e.g. Lakebase
|
|
49
|
+
* `must be owner of table …` on `ALTER`) is logged once instead of rethrown
|
|
50
|
+
* on every storage call.
|
|
51
|
+
*
|
|
52
|
+
* Mastra's `augmentWithInit` retries init forever when it throws, so the
|
|
53
|
+
* only way to keep serving against an already-usable schema is to treat
|
|
54
|
+
* migration failure as success and mark the store initialized.
|
|
55
|
+
*/
|
|
56
|
+
export function withSoftStorageInit(store) {
|
|
57
|
+
const soft = store;
|
|
58
|
+
const originalInit = soft.init.bind(soft);
|
|
59
|
+
soft.init = async () => {
|
|
60
|
+
try {
|
|
61
|
+
await originalInit();
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (isDebugEnabled()) {
|
|
65
|
+
logger.error("mastra storage migration failed", err);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
logger.warn("mastra storage migration failed", {
|
|
69
|
+
error: error.errorMessage(err),
|
|
70
|
+
storeId: soft.id,
|
|
71
|
+
schema: soft.schema,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
soft.isInitialized = true;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
return store;
|
|
78
|
+
}
|
|
40
79
|
/**
|
|
41
80
|
* Build a dedicated **service-principal** Lakebase pool for Mastra
|
|
42
81
|
* memory from the lakebase plugin's resolved SP pg config.
|
|
@@ -116,13 +155,13 @@ export class MemoryBuilder {
|
|
|
116
155
|
if (!setting)
|
|
117
156
|
return undefined;
|
|
118
157
|
if (typeof setting === "object") {
|
|
119
|
-
return new PostgresStore(withId(setting, "mastra-store__instance"));
|
|
158
|
+
return withSoftStorageInit(new PostgresStore(withId(setting, "mastra-store__instance")));
|
|
120
159
|
}
|
|
121
|
-
return new PostgresStore({
|
|
160
|
+
return withSoftStorageInit(new PostgresStore({
|
|
122
161
|
id: "mastra-store__instance",
|
|
123
162
|
schemaName: "mastra_instance",
|
|
124
163
|
pool: this.servicePrincipalPool,
|
|
125
|
-
});
|
|
164
|
+
}));
|
|
126
165
|
}
|
|
127
166
|
/**
|
|
128
167
|
* Build a `Memory` for `agentId` after the plugin/agent cascade.
|
|
@@ -172,16 +211,16 @@ export class MemoryBuilder {
|
|
|
172
211
|
if (!setting)
|
|
173
212
|
return undefined;
|
|
174
213
|
if (typeof setting === "boolean") {
|
|
175
|
-
return new PostgresStore({
|
|
214
|
+
return withSoftStorageInit(new PostgresStore({
|
|
176
215
|
id: `mastra-store__${agentId}`,
|
|
177
216
|
schemaName: agentStorageSchemaName(agentId),
|
|
178
217
|
pool: this.servicePrincipalPool,
|
|
179
|
-
});
|
|
218
|
+
}));
|
|
180
219
|
}
|
|
181
220
|
// Cast: `withId` guarantees `id` is set, but the distributive
|
|
182
221
|
// Omit + `id?: string` shape doesn't structurally narrow to the
|
|
183
222
|
// discriminated union members. Runtime shape is identical.
|
|
184
|
-
return new PostgresStore(withId(setting, `mastra-store__${agentId}`));
|
|
223
|
+
return withSoftStorageInit(new PostgresStore(withId(setting, `mastra-store__${agentId}`)));
|
|
185
224
|
}
|
|
186
225
|
/**
|
|
187
226
|
* Resolve the agent's vector store. Cascade:
|
|
@@ -272,4 +311,4 @@ function collectAgentDefinitions(config) {
|
|
|
272
311
|
function withId(value, fallback) {
|
|
273
312
|
return value.id ? value : { ...value, id: fallback };
|
|
274
313
|
}
|
|
275
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21lbW9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFFSCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDckQsT0FBTyxFQUFFLElBQUksRUFBbUIsTUFBTSxJQUFJLENBQUM7QUFJM0MsT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDN0QsT0FBTyxFQUFFLFlBQVksRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWxFLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFFM0M7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsMEJBQTBCLENBQUMsUUFBb0I7SUFDbkUsOERBQThEO0lBQzlELGdFQUFnRTtJQUNoRSxvRUFBb0U7SUFDcEUsbUNBQW1DO0lBQ25DLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLHdCQUF3QixFQUFFLENBQUMsQ0FBQztJQUNqRSxPQUFPLElBQUksSUFBSSxDQUFDLEVBQUUsR0FBRyxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUN6QyxDQUFDO0FBTUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUFDLE1BQTBCO0lBQ3RE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O0lBQzlDLE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFFRCx5RUFBeUU7QUFDekUsU0FBUyxhQUFhLENBQUMsT0FBbUM7SUFDeEQsT0FBTyxJQUFJLFFBQVEsQ0FDakIsTUFBTSxDQUFDLE9BQU8sRUFBRSxjQUFjLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUE4QyxDQUN4RixDQUFDO0FBQ0osQ0FBQztBQUVELGdFQUFnRTtBQUNoRSxTQUFTLHNCQUFzQixDQUFDLE9BQW1EO0lBQ2pGLE9BQU8sT0FBTyxLQUFLLElBQUksQ0FBQztBQUMxQixDQUFDO0FBRUQsaUVBQWlFO0FBQ2pFLFNBQVMsdUJBQXVCLENBQUMsTUFBMEI7SUFDekQsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztJQUM3QixJQUFJLENBQUMsTUFBTTtRQUFFLE9BQU8sRUFBRSxDQUFDO0lBQ3ZCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUN6QyxJQUFJLE9BQVEsTUFBZ0MsQ0FBQyxZQUFZLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDdkUsT0FBTyxDQUFDLE1BQStCLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLE1BQStDLENBQUMsQ0FBQztBQUN4RSxDQUFDO0FBRUQsZ0VBQWdFO0FBQ2hFLFNBQVMsTUFBTSxDQUE0QixLQUFRLEVBQUUsUUFBZ0I7SUFDbkUsT0FBTyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxLQUFLLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDO0FBQ3ZELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExha2ViYXNlLWJhY2tlZCBNYXN0cmEgbWVtb3J5IHdpcmluZy5cbiAqXG4gKiBQcm92aWRlcyBhIHtAbGluayBNZW1vcnlCdWlsZGVyfSB0aGF0IG1pbnRzIG9uZSBgTWVtb3J5YCBwZXIgYWdlbnRcbiAqIHdpdGggdHdvIGluZGVwZW5kZW50IGtub2JzOlxuICpcbiAqIC0gKipTdG9yYWdlKiogKHRocmVhZHMgLyBtZXNzYWdlcyB2aWEgYFBvc3RncmVzU3RvcmVgKTogZGVmYXVsdHMgdG9cbiAqICAgKipwZXItYWdlbnQqKiBuYW1lc3BhY2luZyB2aWEge0BsaW5rIGFnZW50U3RvcmFnZVNjaGVtYU5hbWV9IHNvXG4gKiAgIGNvbnZlcnNhdGlvbiBoaXN0b3J5IHN0YXlzIGlzb2xhdGVkIGJldHdlZW4gYWdlbnRzIGluIHRoZSBzYW1lXG4gKiAgIGRhdGFiYXNlLiBgUG9zdGdyZXNTdG9yZWAgYXV0by1jcmVhdGVzIHRoZSBzY2hlbWEgd2l0aFxuICogICBgQ1JFQVRFIFNDSEVNQSBJRiBOT1QgRVhJU1RTYCBvbiBpbml0LlxuICogLSAqKk1lbW9yeSoqIChzZW1hbnRpYyByZWNhbGwgdmlhIGBQZ1ZlY3RvcmApOiBkZWZhdWx0cyB0byBhIHNpbmdsZVxuICogICAqKnNoYXJlZCoqIGluc3RhbmNlIGFjcm9zcyBldmVyeSBhZ2VudC4gQ3Jvc3MtYWdlbnQgcmVjYWxsIG9uIG9uZVxuICogICBpbmRleCBpcyBhbG1vc3QgYWx3YXlzIHdoYXQgdXNlcnMgd2FudDsgb3B0IGludG8gcGVyLWFnZW50IHJlY2FsbFxuICogICBieSBwYXNzaW5nIGEge0BsaW5rIE1hc3RyYU1lbW9yeUNvbmZpZ092ZXJyaWRlfSBvbiB0aGUgYWdlbnQuXG4gKlxuICogQWRkaXRpb25hbGx5LCB7QGxpbmsgTWVtb3J5QnVpbGRlci5pbnN0YW5jZVN0b3JhZ2V9IHJldHVybnMgYVxuICogKipNYXN0cmEtaW5zdGFuY2UtbGV2ZWwqKiBgUG9zdGdyZXNTdG9yZWAgKHNjaGVtYSBgbWFzdHJhX2luc3RhbmNlYClcbiAqIHVzZWQgZm9yIHdvcmtmbG93IHNuYXBzaG90cyAtIHRoZSBwZXJzaXN0ZW5jZSBsYXllclxuICogYGFnZW50LnJlc3VtZVN0cmVhbSgpYCByZWFkcyBmcm9tIHdoZW4gd2FraW5nIGEgc3VzcGVuZGVkXG4gKiBgcmVxdWlyZUFwcHJvdmFsYCB0b29sIGNhbGwuIFBlci1hZ2VudCBzdG9yZXMgYXJlIG5vdCBlbm91Z2ggZm9yXG4gKiB0aGlzOiB3b3JrZmxvdyBydW5zIGFyZSBzY29wZWQgdG8gdGhlIE1hc3RyYSBpbnN0YW5jZSwgbm90IGFuXG4gKiBpbmRpdmlkdWFsIGFnZW50J3MgYE1lbW9yeWAuXG4gKlxuICogUGx1Z2luLWxldmVsIGBjb25maWcuc3RvcmFnZWAgLyBgY29uZmlnLm1lbW9yeWAgYWN0IGFzIHRoZSBiYXNlbGluZVxuICogKGF1dG8tZGVmYXVsdGVkIHRvIGB0cnVlYCBpbiBgcGx1Z2luLnRzYCB3aGVuIHRoZSBgbGFrZWJhc2VgIHBsdWdpblxuICogaXMgcmVnaXN0ZXJlZCk7IHBlci1hZ2VudCBzZXR0aW5ncyBjYXNjYWRlIG9uIHRvcCBvZiB0aGF0LlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBnZXRVc2VybmFtZVdpdGhBcGlMb29rdXAgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBoYXNoLCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgZmFzdGVtYmVkIH0gZnJvbSBcIkBtYXN0cmEvZmFzdGVtYmVkXCI7XG5pbXBvcnQgeyBNZW1vcnkgfSBmcm9tIFwiQG1hc3RyYS9tZW1vcnlcIjtcbmltcG9ydCB7IFBnVmVjdG9yLCBQb3N0Z3Jlc1N0b3JlIH0gZnJvbSBcIkBtYXN0cmEvcGdcIjtcbmltcG9ydCB7IFBvb2wsIHR5cGUgUG9vbENvbmZpZyB9IGZyb20gXCJwZ1wiO1xuXG5pbXBvcnQgdHlwZSB7IE1hc3RyYUFnZW50RGVmaW5pdGlvbiwgTWFzdHJhTWVtb3J5Q29uZmlnT3ZlcnJpZGUgfSBmcm9tIFwiLi9hZ2VudHMudHNcIjtcbmltcG9ydCB0eXBlIHsgTWFzdHJhUGx1Z2luQ29uZmlnIH0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBhZ2VudFN0b3JhZ2VTY2hlbWFOYW1lIH0gZnJvbSBcIi4vc3RvcmFnZS1zY2hlbWEudHNcIjtcbmltcG9ydCB7IHN1bW1hcnlNb2RlbCwgVElUTEVfSU5TVFJVQ1RJT05TIH0gZnJvbSBcIi4vc3VtbWFyaXplLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvbWVtb3J5XCIpO1xuXG4vKipcbiAqIEJ1aWxkIGEgZGVkaWNhdGVkICoqc2VydmljZS1wcmluY2lwYWwqKiBMYWtlYmFzZSBwb29sIGZvciBNYXN0cmFcbiAqIG1lbW9yeSBmcm9tIHRoZSBsYWtlYmFzZSBwbHVnaW4ncyByZXNvbHZlZCBTUCBwZyBjb25maWcuXG4gKlxuICogVGhlIHBsdWdpbidzIGBleHBvcnRzKCkucG9vbGAgaXMgYSBgUm91dGluZ1Bvb2xgIHRoYXQgc3dpdGNoZXMgdG9cbiAqIHRoZSBwZXItdXNlciAoT0JPKSBwb29sIHdoZW5ldmVyIGEgcXVlcnkgcnVucyBpbnNpZGUgYW4gYGFzVXNlcmBcbiAqIHNjb3BlIC0gZXhhY3RseSB0aGUgY29udGV4dCB0aGUgbWFzdHJhIHBsdWdpbiBlc3RhYmxpc2hlcyBhcm91bmRcbiAqIGV2ZXJ5IGNoYXQgdHVybi4gTWVtb3J5ICh0aHJlYWRzIC8gbWVzc2FnZXMgKyBzZW1hbnRpYyByZWNhbGwpIG11c3RcbiAqIGluc3RlYWQgYWx3YXlzIGFjdCBhcyB0aGUgYXBwIHNlcnZpY2UgcHJpbmNpcGFsOiBpdCBvd25zIHRoZVxuICogYXV0by1jcmVhdGVkIGBtYXN0cmFfKmAgc2NoZW1hcyAoYSBwZXItdXNlciByb2xlIHVzdWFsbHkgY2FuJ3RcbiAqIGBDUkVBVEUgU0NIRU1BYCkgYW5kIGlzIHNoYXJlZCBhY3Jvc3MgdXNlcnMsIHNvIGl0IGNhbm5vdCBpbmhlcml0IGFcbiAqIHJlcXVlc3QncyBPQk8gaWRlbnRpdHkuXG4gKlxuICogYHBnQ29uZmlnYCBtdXN0IGJlIHRoZSBwbHVnaW4ncyBgZXhwb3J0cygpLmdldFBnQ29uZmlnKClgIGV2YWx1YXRlZFxuICogKipvdXRzaWRlKiogYW55IGBhc1VzZXJgIHNjb3BlIChpLmUuIGR1cmluZyBzZXR1cCksIHNvIGl0IGNhcnJpZXNcbiAqIHRoZSBTUCBjb25uZWN0aW9uIHRhcmdldCwgT0F1dGggdG9rZW4tcmVmcmVzaCBgcGFzc3dvcmRgIGNhbGxiYWNrLFxuICogYW5kIGFueSBgbGFrZWJhc2UoeyBwb29sIH0pYCB0dW5pbmcgb3ZlcnJpZGVzIC0gYWxsIG9mIHdoaWNoIHRoaXNcbiAqIHBvb2wgaW5oZXJpdHMuIFNlZSB0aGUgY2FsbCBzaXRlIGluIGBwbHVnaW4udHNgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlU2VydmljZVByaW5jaXBhbFBvb2wocGdDb25maWc6IFBvb2xDb25maWcpOiBQcm9taXNlPFBvb2w+IHtcbiAgLy8gYGdldFBnQ29uZmlnKClgIHJlc29sdmVzIHRoZSBTUCB1c2VybmFtZSBzeW5jaHJvbm91c2x5IGZyb21cbiAgLy8gYFBHVVNFUmAgLyBgREFUQUJSSUNLU19DTElFTlRfSURgOyBmYWxsIGJhY2sgdG8gdGhlIGFzeW5jIEFQSVxuICAvLyBsb29rdXAgKGUuZy4gbG9jYWwgZGV2IGF1dGhlbnRpY2F0aW5nIHZpYSBQQVQpIHNvIHRoZSBwb29sIGFsd2F5c1xuICAvLyBoYXMgYW4gaWRlbnRpdHkgdG8gY29ubmVjdCB3aXRoLlxuICBjb25zdCB1c2VyID0gcGdDb25maWcudXNlciA/PyAoYXdhaXQgZ2V0VXNlcm5hbWVXaXRoQXBpTG9va3VwKCkpO1xuICByZXR1cm4gbmV3IFBvb2woeyAuLi5wZ0NvbmZpZywgdXNlciB9KTtcbn1cblxuLyoqIEVmZmVjdGl2ZSBwZXIta25vYiBzZXR0aW5nIGFmdGVyIHRoZSBwbHVnaW4vYWdlbnQgY2FzY2FkZS4gKi9cbnR5cGUgU3RvcmFnZVNldHRpbmcgPSBNYXN0cmFBZ2VudERlZmluaXRpb25bXCJzdG9yYWdlXCJdO1xudHlwZSBNZW1vcnlTZXR0aW5nID0gTWFzdHJhQWdlbnREZWZpbml0aW9uW1wibWVtb3J5XCJdO1xuXG4vKipcbiAqIFRydWUgd2hlbiBhbnkgcGx1Z2luLWxldmVsIG9yIHBlci1hZ2VudCBzZXR0aW5nIGNvdWxkIG5lZWQgdGhlXG4gKiBMYWtlYmFzZSBwb29sLiBVc2VkIGJ5IGBwbHVnaW4udHNgIHRvIGdhdGUgY3JlYXRpb24gb2YgdGhlXG4gKiBzZXJ2aWNlLXByaW5jaXBhbCBwb29sIGFuZCB0aGUge0BsaW5rIE1lbW9yeUJ1aWxkZXJ9IHRoYXQgY29uc3VtZXNcbiAqIGl0OyB3aGVuIGZhbHNlIG5laXRoZXIgaXMgYnVpbHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZWVkc0xha2ViYXNlKGNvbmZpZzogTWFzdHJhUGx1Z2luQ29uZmlnKTogYm9vbGVhbiB7XG4gIGlmIChzZXR0aW5nTmVlZHNTaGFyZWRQb29sKGNvbmZpZy5zdG9yYWdlKSkgcmV0dXJuIHRydWU7XG4gIGlmIChzZXR0aW5nTmVlZHNTaGFyZWRQb29sKGNvbmZpZy5tZW1vcnkpKSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgZGVmcyA9IGNvbGxlY3RBZ2VudERlZmluaXRpb25zKGNvbmZpZyk7XG4gIHJldHVybiBkZWZzLnNvbWUoKGQpID0+IHNldHRpbmdOZWVkc1NoYXJlZFBvb2woZC5zdG9yYWdlKSB8fCBzZXR0aW5nTmVlZHNTaGFyZWRQb29sKGQubWVtb3J5KSk7XG59XG5cbi8qKlxuICogQ29uc3RydWN0IGEgcGVyLWFnZW50IHtAbGluayBNZW1vcnl9IGZhY3RvcnkgYm91bmQgdG8gdGhlIHN1cHBsaWVkXG4gKiBzZXJ2aWNlLXByaW5jaXBhbCBwb29sIChzZWUge0BsaW5rIGNyZWF0ZVNlcnZpY2VQcmluY2lwYWxQb29sfSkuXG4gKiBDYWNoZXMgdGhlIHNoYXJlZCBgUGdWZWN0b3JgIHNpbmdsZXRvbiAoYnVpbHQgb24gZmlyc3QgbmVlZCkgc28gZWFjaFxuICogYWdlbnQgYnVpbGQgaXMgTygxKSBhZnRlciB0aGUgZmlyc3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVNZW1vcnlCdWlsZGVyKFxuICBjb25maWc6IE1hc3RyYVBsdWdpbkNvbmZpZyxcbiAgc2VydmljZVByaW5jaXBhbFBvb2w6IFBvb2wsXG4pOiBNZW1vcnlCdWlsZGVyIHtcbiAgcmV0dXJuIG5ldyBNZW1vcnlCdWlsZGVyKGNvbmZpZywgc2VydmljZVByaW5jaXBhbFBvb2wpO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBvbmUgYE1lbW9yeWAgcGVyIGFnZW50IGFnYWluc3QgYSBzaGFyZWQgc2VydmljZS1wcmluY2lwYWxcbiAqIExha2ViYXNlIHBvb2wuIFBlci1pbnN0YW5jZSBzdGF0ZSBrZWVwcyB0aGUgc2hhcmVkIGBQZ1ZlY3RvcmAgYWxpdmVcbiAqIGFjcm9zcyBjYWxscyBzbyByZWdpc3RlcmluZyBOIGFnZW50cyBzdGF5cyBjaGVhcC5cbiAqL1xuZXhwb3J0IGNsYXNzIE1lbW9yeUJ1aWxkZXIge1xuICBwcml2YXRlIHNoYXJlZFZlY3RvcjogUGdWZWN0b3IgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25maWc6IE1hc3RyYVBsdWdpbkNvbmZpZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNlcnZpY2VQcmluY2lwYWxQb29sOiBQb29sLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEJ1aWxkIHRoZSBNYXN0cmEtaW5zdGFuY2UtbGV2ZWwgc3RvcmFnZSB1c2VkIGZvciB3b3JrZmxvd1xuICAgKiBzbmFwc2hvdHMuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiBwbHVnaW4tbGV2ZWwgYHN0b3JhZ2VgIGlzXG4gICAqIGRpc2FibGVkLCBpbiB3aGljaCBjYXNlIGBhZ2VudC5yZXN1bWVTdHJlYW0oKWAgKGFuZCB0aGVyZWZvcmVcbiAgICogdGhlIGByZXF1aXJlQXBwcm92YWxgIGZsb3cpIHdpbGwgbm90IGJlIGF2YWlsYWJsZS5cbiAgICpcbiAgICogVGhlIHN0b3JlIGxpdmVzIGluIGEgZGVkaWNhdGVkIGBtYXN0cmFfaW5zdGFuY2VgIHNjaGVtYSBzbyBpdFxuICAgKiBuZXZlciBjb2xsaWRlcyB3aXRoIHBlci1hZ2VudCB7QGxpbmsgYWdlbnRTdG9yYWdlU2NoZW1hTmFtZX0gbmFtZXNwYWNlcy5cbiAgICogV29ya2Zsb3cgc25hcHNob3RzIGFyZSBub3QgcGVyLWFnZW50IHN0YXRlOyB0aGV5IGJlbG9uZyB0byB0aGVcbiAgICogYE1hc3RyYWAgaW5zdGFuY2UgdGhhdCBvd25zIHRoZSB3b3JrZmxvdyBleGVjdXRpb24uXG4gICAqL1xuICBpbnN0YW5jZVN0b3JhZ2UoKTogUG9zdGdyZXNTdG9yZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc2V0dGluZyA9IHRoaXMuY29uZmlnLnN0b3JhZ2U7XG4gICAgaWYgKCFzZXR0aW5nKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmICh0eXBlb2Ygc2V0dGluZyA9PT0gXCJvYmplY3RcIikge1xuICAgICAgcmV0dXJuIG5ldyBQb3N0Z3Jlc1N0b3JlKFxuICAgICAgICB3aXRoSWQoc2V0dGluZywgXCJtYXN0cmEtc3RvcmVfX2luc3RhbmNlXCIpIGFzIENvbnN0cnVjdG9yUGFyYW1ldGVyczx0eXBlb2YgUG9zdGdyZXNTdG9yZT5bMF0sXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IFBvc3RncmVzU3RvcmUoe1xuICAgICAgaWQ6IFwibWFzdHJhLXN0b3JlX19pbnN0YW5jZVwiLFxuICAgICAgc2NoZW1hTmFtZTogXCJtYXN0cmFfaW5zdGFuY2VcIixcbiAgICAgIHBvb2w6IHRoaXMuc2VydmljZVByaW5jaXBhbFBvb2wsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQnVpbGQgYSBgTWVtb3J5YCBmb3IgYGFnZW50SWRgIGFmdGVyIHRoZSBwbHVnaW4vYWdlbnQgY2FzY2FkZS5cbiAgICogUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHRoZSBhZ2VudCBoYXMgbmVpdGhlciBzdG9yYWdlIG5vciBhXG4gICAqIHZlY3RvciBzdG9yZSBlbmFibGVkIC0gTWFzdHJhIGFjY2VwdHMgYSBtaXNzaW5nIGBtZW1vcnlgIGZpZWxkXG4gICAqIGFuZCB0cmVhdHMgdGhlIGFnZW50IGFzIHN0YXRlbGVzcy5cbiAgICovXG4gIGZvckFnZW50KGFnZW50SWQ6IHN0cmluZywgZGVmOiBNYXN0cmFBZ2VudERlZmluaXRpb24pOiBNZW1vcnkgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHN0b3JhZ2VTZXR0aW5nID0gZGVmLnN0b3JhZ2UgPz8gdGhpcy5jb25maWcuc3RvcmFnZTtcbiAgICBjb25zdCBtZW1vcnlTZXR0aW5nID0gZGVmLm1lbW9yeSA/PyB0aGlzLmNvbmZpZy5tZW1vcnk7XG5cbiAgICBjb25zdCBzdG9yYWdlID0gdGhpcy5idWlsZFN0b3JhZ2UoYWdlbnRJZCwgc3RvcmFnZVNldHRpbmcpO1xuICAgIGNvbnN0IHZlY3RvciA9IHRoaXMuYnVpbGRWZWN0b3IobWVtb3J5U2V0dGluZyk7XG4gICAgaWYgKCFzdG9yYWdlICYmICF2ZWN0b3IpIHtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhcImFnZW50OnN0YXRlbGVzc1wiLCB7IGFnZW50SWQgfSk7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cblxuICAgIGxvZ2dlci5kZWJ1ZyhcImFnZW50OmNvbmZpZ3VyZWRcIiwge1xuICAgICAgYWdlbnRJZCxcbiAgICAgIHN0b3JhZ2U6IHN0b3JhZ2UgIT09IHVuZGVmaW5lZCxcbiAgICAgIHZlY3RvcjogdmVjdG9yICE9PSB1bmRlZmluZWQsXG4gICAgICB2ZWN0b3JNb2RlOlxuICAgICAgICB2ZWN0b3IgPT09IHVuZGVmaW5lZCA/IFwib2ZmXCIgOiB0eXBlb2YgbWVtb3J5U2V0dGluZyA9PT0gXCJvYmplY3RcIiA/IFwiZGVkaWNhdGVkXCIgOiBcInNoYXJlZFwiLFxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5ldyBNZW1vcnkoe1xuICAgICAgLi4uKHN0b3JhZ2UgPyB7IHN0b3JhZ2UgfSA6IHt9KSxcbiAgICAgIC4uLih2ZWN0b3IgPyB7IHZlY3RvciwgZW1iZWRkZXI6IGZhc3RlbWJlZCB9IDoge30pLFxuICAgICAgb3B0aW9uczoge1xuICAgICAgICBsYXN0TWVzc2FnZXM6IDEwLFxuICAgICAgICAuLi4odmVjdG9yID8geyBzZW1hbnRpY1JlY2FsbDogeyB0b3BLOiAzLCBtZXNzYWdlUmFuZ2U6IDIgfSB9IDoge30pLFxuICAgICAgICAvLyBBdXRvLW5hbWUgZWFjaCB0aHJlYWQgZnJvbSBpdHMgb3BlbmluZyB0dXJuIHNvIHRoZVxuICAgICAgICAvLyBjb252ZXJzYXRpb24gbGlzdCB0aGUgVUkgcmVuZGVycyBzaG93cyBtZWFuaW5nZnVsIHRpdGxlc1xuICAgICAgICAvLyBpbnN0ZWFkIG9mIHJhdyBpZHMuIFRpdGxpbmcgcnVucyBvbiB0aGUgc21hbGwgLyBmYXN0IGNoYXRcbiAgICAgICAgLy8gdGllciAoc2VlIGBzdW1tYXJpemUudHNgKSByYXRoZXIgdGhhbiB0aGUgYWdlbnQncyBwcmltYXJ5XG4gICAgICAgIC8vIG1vZGVsLCBzbyBuYW1pbmcgYSB0aHJlYWQgbmV2ZXIgc3BlbmRzIHRoZSBoZWF2eXdlaWdodCBtb2RlbC5cbiAgICAgICAgLy8gT25seSBtZWFuaW5nZnVsIHdoZW4gc3RvcmFnZSBpcyBvbjsgaGFybWxlc3Mgb3RoZXJ3aXNlLlxuICAgICAgICAuLi4oc3RvcmFnZVxuICAgICAgICAgID8ge1xuICAgICAgICAgICAgICBnZW5lcmF0ZVRpdGxlOiB7XG4gICAgICAgICAgICAgICAgbW9kZWw6IHN1bW1hcnlNb2RlbCh0aGlzLmNvbmZpZyksXG4gICAgICAgICAgICAgICAgaW5zdHJ1Y3Rpb25zOiBUSVRMRV9JTlNUUlVDVElPTlMsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9XG4gICAgICAgICAgOiB7fSksXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFN0b3JhZ2UoYWdlbnRJZDogc3RyaW5nLCBzZXR0aW5nOiBTdG9yYWdlU2V0dGluZyk6IFBvc3RncmVzU3RvcmUgfCB1bmRlZmluZWQge1xuICAgIGlmICghc2V0dGluZykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAodHlwZW9mIHNldHRpbmcgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICByZXR1cm4gbmV3IFBvc3RncmVzU3RvcmUoe1xuICAgICAgICBpZDogYG1hc3RyYS1zdG9yZV9fJHthZ2VudElkfWAsXG4gICAgICAgIHNjaGVtYU5hbWU6IGFnZW50U3RvcmFnZVNjaGVtYU5hbWUoYWdlbnRJZCksXG4gICAgICAgIHBvb2w6IHRoaXMuc2VydmljZVByaW5jaXBhbFBvb2wsXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gQ2FzdDogYHdpdGhJZGAgZ3VhcmFudGVlcyBgaWRgIGlzIHNldCwgYnV0IHRoZSBkaXN0cmlidXRpdmVcbiAgICAvLyBPbWl0ICsgYGlkPzogc3RyaW5nYCBzaGFwZSBkb2Vzbid0IHN0cnVjdHVyYWxseSBuYXJyb3cgdG8gdGhlXG4gICAgLy8gZGlzY3JpbWluYXRlZCB1bmlvbiBtZW1iZXJzLiBSdW50aW1lIHNoYXBlIGlzIGlkZW50aWNhbC5cbiAgICByZXR1cm4gbmV3IFBvc3RncmVzU3RvcmUoXG4gICAgICB3aXRoSWQoc2V0dGluZywgYG1hc3RyYS1zdG9yZV9fJHthZ2VudElkfWApIGFzIENvbnN0cnVjdG9yUGFyYW1ldGVyczx0eXBlb2YgUG9zdGdyZXNTdG9yZT5bMF0sXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBhZ2VudCdzIHZlY3RvciBzdG9yZS4gQ2FzY2FkZTpcbiAgICpcbiAgICogLSBmYWxzeTogbm8gdmVjdG9yLlxuICAgKiAtIGBib29sZWFuYCAvIGB1bmRlZmluZWQtaW5oZXJpdGluZy10cnVlYDogcmV0dXJuIHRoZSBzaGFyZWRcbiAgICogICBzaW5nbGV0b24gKGJ1aWx0IGxhemlseSBvbiBmaXJzdCBjYWxsKS4gQWxsIGFnZW50cyB0aGF0XG4gICAqICAgZGVmYXVsdC1lbmFibGUgbWVtb3J5IHdyaXRlIGludG8gYW5kIHJlY2FsbCBmcm9tIG9uZSBpbmRleC5cbiAgICogLSBvYmplY3Q6IGJ1aWxkIGEgZGVkaWNhdGVkIGBQZ1ZlY3RvcmAgZm9yIHRoaXMgYWdlbnQuXG4gICAqL1xuICBwcml2YXRlIGJ1aWxkVmVjdG9yKHNldHRpbmc6IE1lbW9yeVNldHRpbmcpOiBQZ1ZlY3RvciB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFzZXR0aW5nKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmICh0eXBlb2Ygc2V0dGluZyA9PT0gXCJib29sZWFuXCIpIHJldHVybiB0aGlzLmdldFNoYXJlZFZlY3RvcigpO1xuICAgIHJldHVybiBidWlsZFBnVmVjdG9yKHNldHRpbmcpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTaGFyZWRWZWN0b3IoKTogUGdWZWN0b3Ige1xuICAgIGlmICghdGhpcy5zaGFyZWRWZWN0b3IpIHtcbiAgICAgIHRoaXMuc2hhcmVkVmVjdG9yID0gYnVpbGRTaGFyZWRQZ1ZlY3Rvcih0aGlzLnNlcnZpY2VQcmluY2lwYWxQb29sKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc2hhcmVkVmVjdG9yO1xuICB9XG59XG5cbi8qKlxuICogQnVpbGQgdGhlIHNoYXJlZCBgUGdWZWN0b3JgIHRoYXQgYmFja3MgdGhlIGRlZmF1bHRcbiAqIGBkZWYubWVtb3J5ID09PSB0cnVlYCBjYXNlIGFjcm9zcyBldmVyeSBhZ2VudC5cbiAqXG4gKiBgUGdWZWN0b3JgJ3MgY29uc3RydWN0b3IgYWNjZXB0cyBvbmx5IGNvbm5lY3Rpb24tc3R5bGUgY29uZmlnc1xuICogKGBIb3N0Q29uZmlnYCAvIGBDb25uZWN0aW9uU3RyaW5nQ29uZmlnYCAvIGBDbGllbnRDb25maWdgKTsgdGhlcmUgaXNcbiAqIG5vIGB7IHBvb2wgfWAgc2hvcnRoYW5kIHRoZSB3YXkgYFBvc3RncmVzU3RvcmVgIGhhcyBvbmUuIFdvcnNlLCB0aGVcbiAqIGNvbnN0cnVjdG9yIHN5bmNocm9ub3VzbHkga2lja3Mgb2ZmIGEgYGNhY2hlV2FybXVwUHJvbWlzZWAgSUlGRSB0aGF0XG4gKiBjYWxscyBgdGhpcy5wb29sLmNvbm5lY3QoKWAgYmVmb3JlIHJldHVybmluZywgc28gd2UgY2FuJ3QgY2xlYW5seVxuICogaGFuZCBpdCBhbiBpbmVydCBjb25maWcgYW5kIHBhdGNoIHRoZSBwb29sIGFmdGVyd2FyZHMuXG4gKlxuICogVGhlIHRyaWNrOiBwYXNzIGlsbGVnYWwtYnV0LXZhbGlkYXRpb24tcGFzc2luZyBwbGFjZWhvbGRlcnMgc28gdGhlXG4gKiB3YXJtdXAncyBgbmV0LmNvbm5lY3QoKWAgcmVqZWN0cyBzeW5jaHJvbm91c2x5IHdpdGggYFJhbmdlRXJyb3JgXG4gKiAoTm9kZSB2YWxpZGF0ZXMgYDAgPD0gcG9ydCA8IDY1NTM2YCkuIFRoZSBJSUZFJ3MgYGNhdGNoIHt9YCBzd2FsbG93c1xuICogaXQsIG5vIEROUyBsb29rdXAgb3IgVENQIGF0dGVtcHQgaGFwcGVucywgYW5kIHdlIHRoZW4gc3dhcFxuICogYHBnVmVjdG9yLnBvb2xgIHRvIHRoZSBsYWtlYmFzZSBwb29sLiBFdmVyeSBzdWJzZXF1ZW50IGBQZ1ZlY3RvcmBcbiAqIG1ldGhvZCByZWFkcyBgdGhpcy5wb29sYCBhdCBjYWxsIHRpbWUsIHNvIGFsbCByZWFsIEkvTyBnb2VzIHRocm91Z2hcbiAqIHRoZSBsYWtlYmFzZSBwb29sIGZyb20gdGhlbiBvbi4gVGhlIHBsYWNlaG9sZGVyIHBvb2wgaXMgYC5lbmQoKWAnZFxuICogc28gaXRzIHNvY2tldCBib29rLWtlZXBpbmcgaXMgcmVsZWFzZWQuXG4gKi9cbmZ1bmN0aW9uIGJ1aWxkU2hhcmVkUGdWZWN0b3IocG9vbDogUG9vbCk6IFBnVmVjdG9yIHtcbiAgY29uc3QgdmVjdG9yID0gbmV3IFBnVmVjdG9yKHtcbiAgICBpZDogYHBnJHtoYXNoLmlkKCl9YCxcbiAgICAvLyBLZWVwIHRoZSByZWNhbGwgaW5kZXggb3V0IG9mIGBwdWJsaWNgOiBvbiBhIExha2ViYXNlIGRhdGFiYXNlIHRoZSBhcHBcbiAgICAvLyBzZXJ2aWNlIHByaW5jaXBhbCBoYXMgbm8gQ1JFQVRFIG9uIGBwdWJsaWNgIChQRzE1KyBsb2NrcyBpdCBkb3duKSwgc28gYVxuICAgIC8vIGRlZmF1bHQtc2NoZW1hIFBnVmVjdG9yIGZhaWxzIG9uIENSRUFURSBJTkRFWCB3aXRoIFwicGVybWlzc2lvbiBkZW5pZWQgZm9yXG4gICAgLy8gc2NoZW1hIHB1YmxpY1wiLiBQZ1ZlY3RvciBydW5zIENSRUFURSBTQ0hFTUEgSUYgTk9UIEVYSVNUUyBmb3IgYSBuYW1lZFxuICAgIC8vIHNjaGVtYSwgc28gdGhlIFNQIGNyZWF0ZXMgYW5kIG93bnMgYG1hc3RyYV9pbnN0YW5jZWAgKHRoZSBzYW1lXG4gICAgLy8gaW5zdGFuY2UtbGV2ZWwgc2NoZW1hIHRoZSB3b3JrZmxvdy1zbmFwc2hvdCBzdG9yZSB1c2VzKSBhbmQgdGhlIGluZGV4XG4gICAgLy8gbGFuZHMgdGhlcmUuIFRhYmxlIG5hbWVzIGRvbid0IGNvbGxpZGUgd2l0aCB0aGUgc3RvcmFnZSB0YWJsZXMuXG4gICAgc2NoZW1hTmFtZTogXCJtYXN0cmFfaW5zdGFuY2VcIixcbiAgICBob3N0OiBcIi0xXCIsXG4gICAgcG9ydDogLTEsXG4gICAgZGF0YWJhc2U6IFwiX1wiLFxuICAgIHVzZXI6IFwiX1wiLFxuICAgIHBhc3N3b3JkOiBcIl9cIixcbiAgfSk7XG4gIGNvbnN0IHBsYWNlaG9sZGVyID0gdmVjdG9yLnBvb2w7XG4gIHZlY3Rvci5wb29sID0gcG9vbDtcbiAgdm9pZCBwbGFjZWhvbGRlci5lbmQoKS5jYXRjaCgoKSA9PiB1bmRlZmluZWQpO1xuICByZXR1cm4gdmVjdG9yO1xufVxuXG4vKiogUGVyLWFnZW50IGRlZGljYXRlZCBgUGdWZWN0b3JgIChyYXJlOyBvcHQtaW4gdmlhIG9iamVjdCBvdmVycmlkZSkuICovXG5mdW5jdGlvbiBidWlsZFBnVmVjdG9yKHNldHRpbmc6IE1hc3RyYU1lbW9yeUNvbmZpZ092ZXJyaWRlKTogUGdWZWN0b3Ige1xuICByZXR1cm4gbmV3IFBnVmVjdG9yKFxuICAgIHdpdGhJZChzZXR0aW5nLCBgcGctdmVjdG9yX18ke2hhc2guaWQoKX1gKSBhcyBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFBnVmVjdG9yPlswXSxcbiAgKTtcbn1cblxuLyoqIFRydWUgd2hlbiB0aGlzIHNldHRpbmcgcmVxdWlyZXMgdGhlIHNoYXJlZCBMYWtlYmFzZSBwb29sLiAqL1xuZnVuY3Rpb24gc2V0dGluZ05lZWRzU2hhcmVkUG9vbChzZXR0aW5nOiBTdG9yYWdlU2V0dGluZyB8IE1lbW9yeVNldHRpbmcgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgcmV0dXJuIHNldHRpbmcgPT09IHRydWU7XG59XG5cbi8qKiBXYWxrIHRoZSB0aHJlZSBzaGFwZXMgb2YgYGNvbmZpZy5hZ2VudHNgIGludG8gYSBmbGF0IGxpc3QuICovXG5mdW5jdGlvbiBjb2xsZWN0QWdlbnREZWZpbml0aW9ucyhjb25maWc6IE1hc3RyYVBsdWdpbkNvbmZpZyk6IE1hc3RyYUFnZW50RGVmaW5pdGlvbltdIHtcbiAgY29uc3QgYWdlbnRzID0gY29uZmlnLmFnZW50cztcbiAgaWYgKCFhZ2VudHMpIHJldHVybiBbXTtcbiAgaWYgKEFycmF5LmlzQXJyYXkoYWdlbnRzKSkgcmV0dXJuIGFnZW50cztcbiAgaWYgKHR5cGVvZiAoYWdlbnRzIGFzIE1hc3RyYUFnZW50RGVmaW5pdGlvbikuaW5zdHJ1Y3Rpb25zID09PSBcInN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIFthZ2VudHMgYXMgTWFzdHJhQWdlbnREZWZpbml0aW9uXTtcbiAgfVxuICByZXR1cm4gT2JqZWN0LnZhbHVlcyhhZ2VudHMgYXMgUmVjb3JkPHN0cmluZywgTWFzdHJhQWdlbnREZWZpbml0aW9uPik7XG59XG5cbi8qKiBGaWxsIGluIGEgZGVmYXVsdCBgaWRgIHdoZW4gdGhlIGNhbGxlciBkaWRuJ3Qgc3VwcGx5IG9uZS4gKi9cbmZ1bmN0aW9uIHdpdGhJZDxUIGV4dGVuZHMgeyBpZD86IHN0cmluZyB9Pih2YWx1ZTogVCwgZmFsbGJhY2s6IHN0cmluZyk6IFQge1xuICByZXR1cm4gdmFsdWUuaWQgPyB2YWx1ZSA6IHsgLi4udmFsdWUsIGlkOiBmYWxsYmFjayB9O1xufVxuIl19
|
|
314
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWVtb3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21lbW9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFFSCxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hDLE9BQU8sRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ3JELE9BQU8sRUFBRSxJQUFJLEVBQW1CLE1BQU0sSUFBSSxDQUFDO0FBSTNDLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQzdELE9BQU8sRUFBRSxZQUFZLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVsRSxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0FBRTNDLDBEQUEwRDtBQUMxRCxTQUFTLGNBQWM7SUFDckIsT0FBTyxHQUFHLENBQUMsY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0FBQ3JDLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxLQUFvQjtJQUN0RCxNQUFNLElBQUksR0FBRyxLQUtaLENBQUM7SUFDRixNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssSUFBSSxFQUFFO1FBQ3JCLElBQUksQ0FBQztZQUNILE1BQU0sWUFBWSxFQUFFLENB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QixNQUFNLENBQUMsT0FBTyxFQUFFLGNBQWMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQThDLENBQ3hGLENBQUM7QUFDSixDQUFDO0FBRUQsZ0VBQWdFO0FBQ2hFLFNBQVMsc0JBQXNCLENBQUMsT0FBbUQ7SUFDakYsT0FBTyxPQUFPLEtBQUssSUFBSSxDQUFDO0FBQzFCLENBQUM7QUFFRCxpRUFBaUU7QUFDakUsU0FBUyx1QkFBdUIsQ0FBQyxNQUEwQjtJQUN6RCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO0lBQzdCLElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdkIsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQztRQUFFLE9BQU8sTUFBTSxDQUFDO0lBQ3pDLElBQUksT0FBUSxNQUFnQyxDQUFDLFlBQVksS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUN2RSxPQUFPLENBQUMsTUFBK0IsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFDRCxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBK0MsQ0FBQyxDQUFDO0FBQ3hFLENBQUM7QUFFRCxnRUFBZ0U7QUFDaEUsU0FBUyxNQUFNLENBQTRCLEtBQVEsRUFBRSxRQUFnQjtJQUNuRSxPQUFPLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLEtBQUssRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUM7QUFDdkQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGFrZWJhc2UtYmFja2VkIE1hc3RyYSBtZW1vcnkgd2lyaW5nLlxuICpcbiAqIFByb3ZpZGVzIGEge0BsaW5rIE1lbW9yeUJ1aWxkZXJ9IHRoYXQgbWludHMgb25lIGBNZW1vcnlgIHBlciBhZ2VudFxuICogd2l0aCB0d28gaW5kZXBlbmRlbnQga25vYnM6XG4gKlxuICogLSAqKlN0b3JhZ2UqKiAodGhyZWFkcyAvIG1lc3NhZ2VzIHZpYSBgUG9zdGdyZXNTdG9yZWApOiBkZWZhdWx0cyB0b1xuICogICAqKnBlci1hZ2VudCoqIG5hbWVzcGFjaW5nIHZpYSB7QGxpbmsgYWdlbnRTdG9yYWdlU2NoZW1hTmFtZX0gc29cbiAqICAgY29udmVyc2F0aW9uIGhpc3Rvcnkgc3RheXMgaXNvbGF0ZWQgYmV0d2VlbiBhZ2VudHMgaW4gdGhlIHNhbWVcbiAqICAgZGF0YWJhc2UuIGBQb3N0Z3Jlc1N0b3JlYCBhdXRvLWNyZWF0ZXMgdGhlIHNjaGVtYSB3aXRoXG4gKiAgIGBDUkVBVEUgU0NIRU1BIElGIE5PVCBFWElTVFNgIG9uIGluaXQuIEEgZmFpbGVkIG1pZ3JhdGlvbiAoY29tbW9uIG9uXG4gKiAgIExha2ViYXNlIHdoZW4gdGhlIGNvbm5lY3Rpbmcgcm9sZSBpcyBub3QgdGhlIHRhYmxlIG93bmVyKSBpcyBsb2dnZWRcbiAqICAgYW5kIHNraXBwZWQgdmlhIHtAbGluayB3aXRoU29mdFN0b3JhZ2VJbml0fSBzbyBleGlzdGluZyB0YWJsZXMga2VlcFxuICogICBzZXJ2aW5nIGluc3RlYWQgb2YgcmV0cnlpbmcgRERMIG9uIGV2ZXJ5IHJlcXVlc3QuXG4gKiAtICoqTWVtb3J5KiogKHNlbWFudGljIHJlY2FsbCB2aWEgYFBnVmVjdG9yYCk6IGRlZmF1bHRzIHRvIGEgc2luZ2xlXG4gKiAgICoqc2hhcmVkKiogaW5zdGFuY2UgYWNyb3NzIGV2ZXJ5IGFnZW50LiBDcm9zcy1hZ2VudCByZWNhbGwgb24gb25lXG4gKiAgIGluZGV4IGlzIGFsbW9zdCBhbHdheXMgd2hhdCB1c2VycyB3YW50OyBvcHQgaW50byBwZXItYWdlbnQgcmVjYWxsXG4gKiAgIGJ5IHBhc3NpbmcgYSB7QGxpbmsgTWFzdHJhTWVtb3J5Q29uZmlnT3ZlcnJpZGV9IG9uIHRoZSBhZ2VudC5cbiAqXG4gKiBBZGRpdGlvbmFsbHksIHtAbGluayBNZW1vcnlCdWlsZGVyLmluc3RhbmNlU3RvcmFnZX0gcmV0dXJucyBhXG4gKiAqKk1hc3RyYS1pbnN0YW5jZS1sZXZlbCoqIGBQb3N0Z3Jlc1N0b3JlYCAoc2NoZW1hIGBtYXN0cmFfaW5zdGFuY2VgKVxuICogdXNlZCBmb3Igd29ya2Zsb3cgc25hcHNob3RzIC0gdGhlIHBlcnNpc3RlbmNlIGxheWVyXG4gKiBgYWdlbnQucmVzdW1lU3RyZWFtKClgIHJlYWRzIGZyb20gd2hlbiB3YWtpbmcgYSBzdXNwZW5kZWRcbiAqIGByZXF1aXJlQXBwcm92YWxgIHRvb2wgY2FsbC4gUGVyLWFnZW50IHN0b3JlcyBhcmUgbm90IGVub3VnaCBmb3JcbiAqIHRoaXM6IHdvcmtmbG93IHJ1bnMgYXJlIHNjb3BlZCB0byB0aGUgTWFzdHJhIGluc3RhbmNlLCBub3QgYW5cbiAqIGluZGl2aWR1YWwgYWdlbnQncyBgTWVtb3J5YC5cbiAqXG4gKiBQbHVnaW4tbGV2ZWwgYGNvbmZpZy5zdG9yYWdlYCAvIGBjb25maWcubWVtb3J5YCBhY3QgYXMgdGhlIGJhc2VsaW5lXG4gKiAoYXV0by1kZWZhdWx0ZWQgdG8gYHRydWVgIGluIGBwbHVnaW4udHNgIHdoZW4gdGhlIGBsYWtlYmFzZWAgcGx1Z2luXG4gKiBpcyByZWdpc3RlcmVkKTsgcGVyLWFnZW50IHNldHRpbmdzIGNhc2NhZGUgb24gdG9wIG9mIHRoYXQuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IGdldFVzZXJuYW1lV2l0aEFwaUxvb2t1cCB9IGZyb20gXCJAZGF0YWJyaWNrcy9hcHBraXRcIjtcbmltcG9ydCB7IGVycm9yLCBoYXNoLCBsb2cgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHsgZmFzdGVtYmVkIH0gZnJvbSBcIkBtYXN0cmEvZmFzdGVtYmVkXCI7XG5pbXBvcnQgeyBNZW1vcnkgfSBmcm9tIFwiQG1hc3RyYS9tZW1vcnlcIjtcbmltcG9ydCB7IFBnVmVjdG9yLCBQb3N0Z3Jlc1N0b3JlIH0gZnJvbSBcIkBtYXN0cmEvcGdcIjtcbmltcG9ydCB7IFBvb2wsIHR5cGUgUG9vbENvbmZpZyB9IGZyb20gXCJwZ1wiO1xuXG5pbXBvcnQgdHlwZSB7IE1hc3RyYUFnZW50RGVmaW5pdGlvbiwgTWFzdHJhTWVtb3J5Q29uZmlnT3ZlcnJpZGUgfSBmcm9tIFwiLi9hZ2VudHMudHNcIjtcbmltcG9ydCB0eXBlIHsgTWFzdHJhUGx1Z2luQ29uZmlnIH0gZnJvbSBcIi4vY29uZmlnLnRzXCI7XG5pbXBvcnQgeyBhZ2VudFN0b3JhZ2VTY2hlbWFOYW1lIH0gZnJvbSBcIi4vc3RvcmFnZS1zY2hlbWEudHNcIjtcbmltcG9ydCB7IHN1bW1hcnlNb2RlbCwgVElUTEVfSU5TVFJVQ1RJT05TIH0gZnJvbSBcIi4vc3VtbWFyaXplLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvbWVtb3J5XCIpO1xuXG4vKiogV2hldGhlciBgTE9HX0xFVkVMYCBpcyBjdXJyZW50bHkgYXQgb3IgYmVsb3cgZGVidWcuICovXG5mdW5jdGlvbiBpc0RlYnVnRW5hYmxlZCgpOiBib29sZWFuIHtcbiAgcmV0dXJuIGxvZy5pc0xldmVsRW5hYmxlZChcImRlYnVnXCIpO1xufVxuXG4vKipcbiAqIFNvZnRlbiB7QGxpbmsgUG9zdGdyZXNTdG9yZS5pbml0fSBzbyBhIGZhaWxlZCBtaWdyYXRpb24gKGUuZy4gTGFrZWJhc2VcbiAqIGBtdXN0IGJlIG93bmVyIG9mIHRhYmxlIOKApmAgb24gYEFMVEVSYCkgaXMgbG9nZ2VkIG9uY2UgaW5zdGVhZCBvZiByZXRocm93blxuICogb24gZXZlcnkgc3RvcmFnZSBjYWxsLlxuICpcbiAqIE1hc3RyYSdzIGBhdWdtZW50V2l0aEluaXRgIHJldHJpZXMgaW5pdCBmb3JldmVyIHdoZW4gaXQgdGhyb3dzLCBzbyB0aGVcbiAqIG9ubHkgd2F5IHRvIGtlZXAgc2VydmluZyBhZ2FpbnN0IGFuIGFscmVhZHktdXNhYmxlIHNjaGVtYSBpcyB0byB0cmVhdFxuICogbWlncmF0aW9uIGZhaWx1cmUgYXMgc3VjY2VzcyBhbmQgbWFyayB0aGUgc3RvcmUgaW5pdGlhbGl6ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoU29mdFN0b3JhZ2VJbml0KHN0b3JlOiBQb3N0Z3Jlc1N0b3JlKTogUG9zdGdyZXNTdG9yZSB7XG4gIGNvbnN0IHNvZnQgPSBzdG9yZSBhcyB1bmtub3duIGFzIHtcbiAgICBpbml0OiAoKSA9PiBQcm9taXNlPHZvaWQ+O1xuICAgIGlkOiBzdHJpbmc7XG4gICAgc2NoZW1hPzogc3RyaW5nO1xuICAgIGlzSW5pdGlhbGl6ZWQ6IGJvb2xlYW47XG4gIH07XG4gIGNvbnN0IG9yaWdpbmFsSW5pdCA9IHNvZnQuaW5pdC5iaW5kKHNvZnQpO1xuICBzb2Z0LmluaXQgPSBhc3luYyAoKSA9PiB7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IG9yaWdpbmFsSW5pdCgpO1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgaWYgKGlzRGVidWdFbmFibGVkKCkpIHtcbiAgICAgICAgbG9nZ2VyLmVycm9yKFwibWFzdHJhIHN0b3JhZ2UgbWlncmF0aW9uIGZhaWxlZFwiLCBlcnIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXCJtYXN0cmEgc3RvcmFnZSBtaWdyYXRpb24gZmFpbGVkXCIsIHtcbiAgICAgICAgICBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGVyciksXG4gICAgICAgICAgc3RvcmVJZDogc29mdC5pZCxcbiAgICAgICAgICBzY2hlbWE6IHNvZnQuc2NoZW1hLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHNvZnQuaXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgfVxuICB9O1xuICByZXR1cm4gc3RvcmU7XG59XG5cbi8qKlxuICogQnVpbGQgYSBkZWRpY2F0ZWQgKipzZXJ2aWNlLXByaW5jaXBhbCoqIExha2ViYXNlIHBvb2wgZm9yIE1hc3RyYVxuICogbWVtb3J5IGZyb20gdGhlIGxha2ViYXNlIHBsdWdpbidzIHJlc29sdmVkIFNQIHBnIGNvbmZpZy5cbiAqXG4gKiBUaGUgcGx1Z2luJ3MgYGV4cG9ydHMoKS5wb29sYCBpcyBhIGBSb3V0aW5nUG9vbGAgdGhhdCBzd2l0Y2hlcyB0b1xuICogdGhlIHBlci11c2VyIChPQk8pIHBvb2wgd2hlbmV2ZXIgYSBxdWVyeSBydW5zIGluc2lkZSBhbiBgYXNVc2VyYFxuICogc2NvcGUgLSBleGFjdGx5IHRoZSBjb250ZXh0IHRoZSBtYXN0cmEgcGx1Z2luIGVzdGFibGlzaGVzIGFyb3VuZFxuICogZXZlcnkgY2hhdCB0dXJuLiBNZW1vcnkgKHRocmVhZHMgLyBtZXNzYWdlcyArIHNlbWFudGljIHJlY2FsbCkgbXVzdFxuICogaW5zdGVhZCBhbHdheXMgYWN0IGFzIHRoZSBhcHAgc2VydmljZSBwcmluY2lwYWw6IGl0IG93bnMgdGhlXG4gKiBhdXRvLWNyZWF0ZWQgYG1hc3RyYV8qYCBzY2hlbWFzIChhIHBlci11c2VyIHJvbGUgdXN1YWxseSBjYW4ndFxuICogYENSRUFURSBTQ0hFTUFgKSBhbmQgaXMgc2hhcmVkIGFjcm9zcyB1c2Vycywgc28gaXQgY2Fubm90IGluaGVyaXQgYVxuICogcmVxdWVzdCdzIE9CTyBpZGVudGl0eS5cbiAqXG4gKiBgcGdDb25maWdgIG11c3QgYmUgdGhlIHBsdWdpbidzIGBleHBvcnRzKCkuZ2V0UGdDb25maWcoKWAgZXZhbHVhdGVkXG4gKiAqKm91dHNpZGUqKiBhbnkgYGFzVXNlcmAgc2NvcGUgKGkuZS4gZHVyaW5nIHNldHVwKSwgc28gaXQgY2Fycmllc1xuICogdGhlIFNQIGNvbm5lY3Rpb24gdGFyZ2V0LCBPQXV0aCB0b2tlbi1yZWZyZXNoIGBwYXNzd29yZGAgY2FsbGJhY2ssXG4gKiBhbmQgYW55IGBsYWtlYmFzZSh7IHBvb2wgfSlgIHR1bmluZyBvdmVycmlkZXMgLSBhbGwgb2Ygd2hpY2ggdGhpc1xuICogcG9vbCBpbmhlcml0cy4gU2VlIHRoZSBjYWxsIHNpdGUgaW4gYHBsdWdpbi50c2AuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjcmVhdGVTZXJ2aWNlUHJpbmNpcGFsUG9vbChwZ0NvbmZpZzogUG9vbENvbmZpZyk6IFByb21pc2U8UG9vbD4ge1xuICAvLyBgZ2V0UGdDb25maWcoKWAgcmVzb2x2ZXMgdGhlIFNQIHVzZXJuYW1lIHN5bmNocm9ub3VzbHkgZnJvbVxuICAvLyBgUEdVU0VSYCAvIGBEQVRBQlJJQ0tTX0NMSUVOVF9JRGA7IGZhbGwgYmFjayB0byB0aGUgYXN5bmMgQVBJXG4gIC8vIGxvb2t1cCAoZS5nLiBsb2NhbCBkZXYgYXV0aGVudGljYXRpbmcgdmlhIFBBVCkgc28gdGhlIHBvb2wgYWx3YXlzXG4gIC8vIGhhcyBhbiBpZGVudGl0eSB0byBjb25uZWN0IHdpdGguXG4gIGNvbnN0IHVzZXIgPSBwZ0NvbmZpZy51c2VyID8/IChhd2FpdCBnZXRVc2VybmFtZVdpdGhBcGlMb29rdXAoKSk7XG4gIHJldHVybiBuZXcgUG9vbCh7IC4uLnBnQ29uZmlnLCB1c2VyIH0pO1xufVxuXG4vKiogRWZmZWN0aXZlIHBlci1rbm9iIHNldHRpbmcgYWZ0ZXIgdGhlIHBsdWdpbi9hZ2VudCBjYXNjYWRlLiAqL1xudHlwZSBTdG9yYWdlU2V0dGluZyA9IE1hc3RyYUFnZW50RGVmaW5pdGlvbltcInN0b3JhZ2VcIl07XG50eXBlIE1lbW9yeVNldHRpbmcgPSBNYXN0cmFBZ2VudERlZmluaXRpb25bXCJtZW1vcnlcIl07XG5cbi8qKlxuICogVHJ1ZSB3aGVuIGFueSBwbHVnaW4tbGV2ZWwgb3IgcGVyLWFnZW50IHNldHRpbmcgY291bGQgbmVlZCB0aGVcbiAqIExha2ViYXNlIHBvb2wuIFVzZWQgYnkgYHBsdWdpbi50c2AgdG8gZ2F0ZSBjcmVhdGlvbiBvZiB0aGVcbiAqIHNlcnZpY2UtcHJpbmNpcGFsIHBvb2wgYW5kIHRoZSB7QGxpbmsgTWVtb3J5QnVpbGRlcn0gdGhhdCBjb25zdW1lc1xuICogaXQ7IHdoZW4gZmFsc2UgbmVpdGhlciBpcyBidWlsdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5lZWRzTGFrZWJhc2UoY29uZmlnOiBNYXN0cmFQbHVnaW5Db25maWcpOiBib29sZWFuIHtcbiAgaWYgKHNldHRpbmdOZWVkc1NoYXJlZFBvb2woY29uZmlnLnN0b3JhZ2UpKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKHNldHRpbmdOZWVkc1NoYXJlZFBvb2woY29uZmlnLm1lbW9yeSkpIHJldHVybiB0cnVlO1xuICBjb25zdCBkZWZzID0gY29sbGVjdEFnZW50RGVmaW5pdGlvbnMoY29uZmlnKTtcbiAgcmV0dXJuIGRlZnMuc29tZSgoZCkgPT4gc2V0dGluZ05lZWRzU2hhcmVkUG9vbChkLnN0b3JhZ2UpIHx8IHNldHRpbmdOZWVkc1NoYXJlZFBvb2woZC5tZW1vcnkpKTtcbn1cblxuLyoqXG4gKiBDb25zdHJ1Y3QgYSBwZXItYWdlbnQge0BsaW5rIE1lbW9yeX0gZmFjdG9yeSBib3VuZCB0byB0aGUgc3VwcGxpZWRcbiAqIHNlcnZpY2UtcHJpbmNpcGFsIHBvb2wgKHNlZSB7QGxpbmsgY3JlYXRlU2VydmljZVByaW5jaXBhbFBvb2x9KS5cbiAqIENhY2hlcyB0aGUgc2hhcmVkIGBQZ1ZlY3RvcmAgc2luZ2xldG9uIChidWlsdCBvbiBmaXJzdCBuZWVkKSBzbyBlYWNoXG4gKiBhZ2VudCBidWlsZCBpcyBPKDEpIGFmdGVyIHRoZSBmaXJzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZU1lbW9yeUJ1aWxkZXIoXG4gIGNvbmZpZzogTWFzdHJhUGx1Z2luQ29uZmlnLFxuICBzZXJ2aWNlUHJpbmNpcGFsUG9vbDogUG9vbCxcbik6IE1lbW9yeUJ1aWxkZXIge1xuICByZXR1cm4gbmV3IE1lbW9yeUJ1aWxkZXIoY29uZmlnLCBzZXJ2aWNlUHJpbmNpcGFsUG9vbCk7XG59XG5cbi8qKlxuICogQnVpbGRzIG9uZSBgTWVtb3J5YCBwZXIgYWdlbnQgYWdhaW5zdCBhIHNoYXJlZCBzZXJ2aWNlLXByaW5jaXBhbFxuICogTGFrZWJhc2UgcG9vbC4gUGVyLWluc3RhbmNlIHN0YXRlIGtlZXBzIHRoZSBzaGFyZWQgYFBnVmVjdG9yYCBhbGl2ZVxuICogYWNyb3NzIGNhbGxzIHNvIHJlZ2lzdGVyaW5nIE4gYWdlbnRzIHN0YXlzIGNoZWFwLlxuICovXG5leHBvcnQgY2xhc3MgTWVtb3J5QnVpbGRlciB7XG4gIHByaXZhdGUgc2hhcmVkVmVjdG9yOiBQZ1ZlY3RvciB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZzogTWFzdHJhUGx1Z2luQ29uZmlnLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZVByaW5jaXBhbFBvb2w6IFBvb2wsXG4gICkge31cblxuICAvKipcbiAgICogQnVpbGQgdGhlIE1hc3RyYS1pbnN0YW5jZS1sZXZlbCBzdG9yYWdlIHVzZWQgZm9yIHdvcmtmbG93XG4gICAqIHNuYXBzaG90cy4gUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIHBsdWdpbi1sZXZlbCBgc3RvcmFnZWAgaXNcbiAgICogZGlzYWJsZWQsIGluIHdoaWNoIGNhc2UgYGFnZW50LnJlc3VtZVN0cmVhbSgpYCAoYW5kIHRoZXJlZm9yZVxuICAgKiB0aGUgYHJlcXVpcmVBcHByb3ZhbGAgZmxvdykgd2lsbCBub3QgYmUgYXZhaWxhYmxlLlxuICAgKlxuICAgKiBUaGUgc3RvcmUgbGl2ZXMgaW4gYSBkZWRpY2F0ZWQgYG1hc3RyYV9pbnN0YW5jZWAgc2NoZW1hIHNvIGl0XG4gICAqIG5ldmVyIGNvbGxpZGVzIHdpdGggcGVyLWFnZW50IHtAbGluayBhZ2VudFN0b3JhZ2VTY2hlbWFOYW1lfSBuYW1lc3BhY2VzLlxuICAgKiBXb3JrZmxvdyBzbmFwc2hvdHMgYXJlIG5vdCBwZXItYWdlbnQgc3RhdGU7IHRoZXkgYmVsb25nIHRvIHRoZVxuICAgKiBgTWFzdHJhYCBpbnN0YW5jZSB0aGF0IG93bnMgdGhlIHdvcmtmbG93IGV4ZWN1dGlvbi5cbiAgICovXG4gIGluc3RhbmNlU3RvcmFnZSgpOiBQb3N0Z3Jlc1N0b3JlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBzZXR0aW5nID0gdGhpcy5jb25maWcuc3RvcmFnZTtcbiAgICBpZiAoIXNldHRpbmcpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKHR5cGVvZiBzZXR0aW5nID09PSBcIm9iamVjdFwiKSB7XG4gICAgICByZXR1cm4gd2l0aFNvZnRTdG9yYWdlSW5pdChcbiAgICAgICAgbmV3IFBvc3RncmVzU3RvcmUoXG4gICAgICAgICAgd2l0aElkKHNldHRpbmcsIFwibWFzdHJhLXN0b3JlX19pbnN0YW5jZVwiKSBhcyBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8XG4gICAgICAgICAgICB0eXBlb2YgUG9zdGdyZXNTdG9yZVxuICAgICAgICAgID5bMF0sXG4gICAgICAgICksXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gd2l0aFNvZnRTdG9yYWdlSW5pdChcbiAgICAgIG5ldyBQb3N0Z3Jlc1N0b3JlKHtcbiAgICAgICAgaWQ6IFwibWFzdHJhLXN0b3JlX19pbnN0YW5jZVwiLFxuICAgICAgICBzY2hlbWFOYW1lOiBcIm1hc3RyYV9pbnN0YW5jZVwiLFxuICAgICAgICBwb29sOiB0aGlzLnNlcnZpY2VQcmluY2lwYWxQb29sLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCBhIGBNZW1vcnlgIGZvciBgYWdlbnRJZGAgYWZ0ZXIgdGhlIHBsdWdpbi9hZ2VudCBjYXNjYWRlLlxuICAgKiBSZXR1cm5zIGB1bmRlZmluZWRgIHdoZW4gdGhlIGFnZW50IGhhcyBuZWl0aGVyIHN0b3JhZ2Ugbm9yIGFcbiAgICogdmVjdG9yIHN0b3JlIGVuYWJsZWQgLSBNYXN0cmEgYWNjZXB0cyBhIG1pc3NpbmcgYG1lbW9yeWAgZmllbGRcbiAgICogYW5kIHRyZWF0cyB0aGUgYWdlbnQgYXMgc3RhdGVsZXNzLlxuICAgKi9cbiAgZm9yQWdlbnQoYWdlbnRJZDogc3RyaW5nLCBkZWY6IE1hc3RyYUFnZW50RGVmaW5pdGlvbik6IE1lbW9yeSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgc3RvcmFnZVNldHRpbmcgPSBkZWYuc3RvcmFnZSA/PyB0aGlzLmNvbmZpZy5zdG9yYWdlO1xuICAgIGNvbnN0IG1lbW9yeVNldHRpbmcgPSBkZWYubWVtb3J5ID8/IHRoaXMuY29uZmlnLm1lbW9yeTtcblxuICAgIGNvbnN0IHN0b3JhZ2UgPSB0aGlzLmJ1aWxkU3RvcmFnZShhZ2VudElkLCBzdG9yYWdlU2V0dGluZyk7XG4gICAgY29uc3QgdmVjdG9yID0gdGhpcy5idWlsZFZlY3RvcihtZW1vcnlTZXR0aW5nKTtcbiAgICBpZiAoIXN0b3JhZ2UgJiYgIXZlY3Rvcikge1xuICAgICAgbG9nZ2VyLmRlYnVnKFwiYWdlbnQ6c3RhdGVsZXNzXCIsIHsgYWdlbnRJZCB9KTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgbG9nZ2VyLmRlYnVnKFwiYWdlbnQ6Y29uZmlndXJlZFwiLCB7XG4gICAgICBhZ2VudElkLFxuICAgICAgc3RvcmFnZTogc3RvcmFnZSAhPT0gdW5kZWZpbmVkLFxuICAgICAgdmVjdG9yOiB2ZWN0b3IgIT09IHVuZGVmaW5lZCxcbiAgICAgIHZlY3Rvck1vZGU6XG4gICAgICAgIHZlY3RvciA9PT0gdW5kZWZpbmVkID8gXCJvZmZcIiA6IHR5cGVvZiBtZW1vcnlTZXR0aW5nID09PSBcIm9iamVjdFwiID8gXCJkZWRpY2F0ZWRcIiA6IFwic2hhcmVkXCIsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gbmV3IE1lbW9yeSh7XG4gICAgICAuLi4oc3RvcmFnZSA/IHsgc3RvcmFnZSB9IDoge30pLFxuICAgICAgLi4uKHZlY3RvciA/IHsgdmVjdG9yLCBlbWJlZGRlcjogZmFzdGVtYmVkIH0gOiB7fSksXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGxhc3RNZXNzYWdlczogMTAsXG4gICAgICAgIC4uLih2ZWN0b3IgPyB7IHNlbWFudGljUmVjYWxsOiB7IHRvcEs6IDMsIG1lc3NhZ2VSYW5nZTogMiB9IH0gOiB7fSksXG4gICAgICAgIC8vIEF1dG8tbmFtZSBlYWNoIHRocmVhZCBmcm9tIGl0cyBvcGVuaW5nIHR1cm4gc28gdGhlXG4gICAgICAgIC8vIGNvbnZlcnNhdGlvbiBsaXN0IHRoZSBVSSByZW5kZXJzIHNob3dzIG1lYW5pbmdmdWwgdGl0bGVzXG4gICAgICAgIC8vIGluc3RlYWQgb2YgcmF3IGlkcy4gVGl0bGluZyBydW5zIG9uIHRoZSBzbWFsbCAvIGZhc3QgY2hhdFxuICAgICAgICAvLyB0aWVyIChzZWUgYHN1bW1hcml6ZS50c2ApIHJhdGhlciB0aGFuIHRoZSBhZ2VudCdzIHByaW1hcnlcbiAgICAgICAgLy8gbW9kZWwsIHNvIG5hbWluZyBhIHRocmVhZCBuZXZlciBzcGVuZHMgdGhlIGhlYXZ5d2VpZ2h0IG1vZGVsLlxuICAgICAgICAvLyBPbmx5IG1lYW5pbmdmdWwgd2hlbiBzdG9yYWdlIGlzIG9uOyBoYXJtbGVzcyBvdGhlcndpc2UuXG4gICAgICAgIC4uLihzdG9yYWdlXG4gICAgICAgICAgPyB7XG4gICAgICAgICAgICAgIGdlbmVyYXRlVGl0bGU6IHtcbiAgICAgICAgICAgICAgICBtb2RlbDogc3VtbWFyeU1vZGVsKHRoaXMuY29uZmlnKSxcbiAgICAgICAgICAgICAgICBpbnN0cnVjdGlvbnM6IFRJVExFX0lOU1RSVUNUSU9OUyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH1cbiAgICAgICAgICA6IHt9KSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGJ1aWxkU3RvcmFnZShhZ2VudElkOiBzdHJpbmcsIHNldHRpbmc6IFN0b3JhZ2VTZXR0aW5nKTogUG9zdGdyZXNTdG9yZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKCFzZXR0aW5nKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmICh0eXBlb2Ygc2V0dGluZyA9PT0gXCJib29sZWFuXCIpIHtcbiAgICAgIHJldHVybiB3aXRoU29mdFN0b3JhZ2VJbml0KFxuICAgICAgICBuZXcgUG9zdGdyZXNTdG9yZSh7XG4gICAgICAgICAgaWQ6IGBtYXN0cmEtc3RvcmVfXyR7YWdlbnRJZH1gLFxuICAgICAgICAgIHNjaGVtYU5hbWU6IGFnZW50U3RvcmFnZVNjaGVtYU5hbWUoYWdlbnRJZCksXG4gICAgICAgICAgcG9vbDogdGhpcy5zZXJ2aWNlUHJpbmNpcGFsUG9vbCxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgICAvLyBDYXN0OiBgd2l0aElkYCBndWFyYW50ZWVzIGBpZGAgaXMgc2V0LCBidXQgdGhlIGRpc3RyaWJ1dGl2ZVxuICAgIC8vIE9taXQgKyBgaWQ/OiBzdHJpbmdgIHNoYXBlIGRvZXNuJ3Qgc3RydWN0dXJhbGx5IG5hcnJvdyB0byB0aGVcbiAgICAvLyBkaXNjcmltaW5hdGVkIHVuaW9uIG1lbWJlcnMuIFJ1bnRpbWUgc2hhcGUgaXMgaWRlbnRpY2FsLlxuICAgIHJldHVybiB3aXRoU29mdFN0b3JhZ2VJbml0KFxuICAgICAgbmV3IFBvc3RncmVzU3RvcmUoXG4gICAgICAgIHdpdGhJZChzZXR0aW5nLCBgbWFzdHJhLXN0b3JlX18ke2FnZW50SWR9YCkgYXMgQ29uc3RydWN0b3JQYXJhbWV0ZXJzPFxuICAgICAgICAgIHR5cGVvZiBQb3N0Z3Jlc1N0b3JlXG4gICAgICAgID5bMF0sXG4gICAgICApLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZSB0aGUgYWdlbnQncyB2ZWN0b3Igc3RvcmUuIENhc2NhZGU6XG4gICAqXG4gICAqIC0gZmFsc3k6IG5vIHZlY3Rvci5cbiAgICogLSBgYm9vbGVhbmAgLyBgdW5kZWZpbmVkLWluaGVyaXRpbmctdHJ1ZWA6IHJldHVybiB0aGUgc2hhcmVkXG4gICAqICAgc2luZ2xldG9uIChidWlsdCBsYXppbHkgb24gZmlyc3QgY2FsbCkuIEFsbCBhZ2VudHMgdGhhdFxuICAgKiAgIGRlZmF1bHQtZW5hYmxlIG1lbW9yeSB3cml0ZSBpbnRvIGFuZCByZWNhbGwgZnJvbSBvbmUgaW5kZXguXG4gICAqIC0gb2JqZWN0OiBidWlsZCBhIGRlZGljYXRlZCBgUGdWZWN0b3JgIGZvciB0aGlzIGFnZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBidWlsZFZlY3RvcihzZXR0aW5nOiBNZW1vcnlTZXR0aW5nKTogUGdWZWN0b3IgfCB1bmRlZmluZWQge1xuICAgIGlmICghc2V0dGluZykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICBpZiAodHlwZW9mIHNldHRpbmcgPT09IFwiYm9vbGVhblwiKSByZXR1cm4gdGhpcy5nZXRTaGFyZWRWZWN0b3IoKTtcbiAgICByZXR1cm4gYnVpbGRQZ1ZlY3RvcihzZXR0aW5nKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2hhcmVkVmVjdG9yKCk6IFBnVmVjdG9yIHtcbiAgICBpZiAoIXRoaXMuc2hhcmVkVmVjdG9yKSB7XG4gICAgICB0aGlzLnNoYXJlZFZlY3RvciA9IGJ1aWxkU2hhcmVkUGdWZWN0b3IodGhpcy5zZXJ2aWNlUHJpbmNpcGFsUG9vbCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnNoYXJlZFZlY3RvcjtcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkIHRoZSBzaGFyZWQgYFBnVmVjdG9yYCB0aGF0IGJhY2tzIHRoZSBkZWZhdWx0XG4gKiBgZGVmLm1lbW9yeSA9PT0gdHJ1ZWAgY2FzZSBhY3Jvc3MgZXZlcnkgYWdlbnQuXG4gKlxuICogYFBnVmVjdG9yYCdzIGNvbnN0cnVjdG9yIGFjY2VwdHMgb25seSBjb25uZWN0aW9uLXN0eWxlIGNvbmZpZ3NcbiAqIChgSG9zdENvbmZpZ2AgLyBgQ29ubmVjdGlvblN0cmluZ0NvbmZpZ2AgLyBgQ2xpZW50Q29uZmlnYCk7IHRoZXJlIGlzXG4gKiBubyBgeyBwb29sIH1gIHNob3J0aGFuZCB0aGUgd2F5IGBQb3N0Z3Jlc1N0b3JlYCBoYXMgb25lLiBXb3JzZSwgdGhlXG4gKiBjb25zdHJ1Y3RvciBzeW5jaHJvbm91c2x5IGtpY2tzIG9mZiBhIGBjYWNoZVdhcm11cFByb21pc2VgIElJRkUgdGhhdFxuICogY2FsbHMgYHRoaXMucG9vbC5jb25uZWN0KClgIGJlZm9yZSByZXR1cm5pbmcsIHNvIHdlIGNhbid0IGNsZWFubHlcbiAqIGhhbmQgaXQgYW4gaW5lcnQgY29uZmlnIGFuZCBwYXRjaCB0aGUgcG9vbCBhZnRlcndhcmRzLlxuICpcbiAqIFRoZSB0cmljazogcGFzcyBpbGxlZ2FsLWJ1dC12YWxpZGF0aW9uLXBhc3NpbmcgcGxhY2Vob2xkZXJzIHNvIHRoZVxuICogd2FybXVwJ3MgYG5ldC5jb25uZWN0KClgIHJlamVjdHMgc3luY2hyb25vdXNseSB3aXRoIGBSYW5nZUVycm9yYFxuICogKE5vZGUgdmFsaWRhdGVzIGAwIDw9IHBvcnQgPCA2NTUzNmApLiBUaGUgSUlGRSdzIGBjYXRjaCB7fWAgc3dhbGxvd3NcbiAqIGl0LCBubyBETlMgbG9va3VwIG9yIFRDUCBhdHRlbXB0IGhhcHBlbnMsIGFuZCB3ZSB0aGVuIHN3YXBcbiAqIGBwZ1ZlY3Rvci5wb29sYCB0byB0aGUgbGFrZWJhc2UgcG9vbC4gRXZlcnkgc3Vic2VxdWVudCBgUGdWZWN0b3JgXG4gKiBtZXRob2QgcmVhZHMgYHRoaXMucG9vbGAgYXQgY2FsbCB0aW1lLCBzbyBhbGwgcmVhbCBJL08gZ29lcyB0aHJvdWdoXG4gKiB0aGUgbGFrZWJhc2UgcG9vbCBmcm9tIHRoZW4gb24uIFRoZSBwbGFjZWhvbGRlciBwb29sIGlzIGAuZW5kKClgJ2RcbiAqIHNvIGl0cyBzb2NrZXQgYm9vay1rZWVwaW5nIGlzIHJlbGVhc2VkLlxuICovXG5mdW5jdGlvbiBidWlsZFNoYXJlZFBnVmVjdG9yKHBvb2w6IFBvb2wpOiBQZ1ZlY3RvciB7XG4gIGNvbnN0IHZlY3RvciA9IG5ldyBQZ1ZlY3Rvcih7XG4gICAgaWQ6IGBwZyR7aGFzaC5pZCgpfWAsXG4gICAgLy8gS2VlcCB0aGUgcmVjYWxsIGluZGV4IG91dCBvZiBgcHVibGljYDogb24gYSBMYWtlYmFzZSBkYXRhYmFzZSB0aGUgYXBwXG4gICAgLy8gc2VydmljZSBwcmluY2lwYWwgaGFzIG5vIENSRUFURSBvbiBgcHVibGljYCAoUEcxNSsgbG9ja3MgaXQgZG93biksIHNvIGFcbiAgICAvLyBkZWZhdWx0LXNjaGVtYSBQZ1ZlY3RvciBmYWlscyBvbiBDUkVBVEUgSU5ERVggd2l0aCBcInBlcm1pc3Npb24gZGVuaWVkIGZvclxuICAgIC8vIHNjaGVtYSBwdWJsaWNcIi4gUGdWZWN0b3IgcnVucyBDUkVBVEUgU0NIRU1BIElGIE5PVCBFWElTVFMgZm9yIGEgbmFtZWRcbiAgICAvLyBzY2hlbWEsIHNvIHRoZSBTUCBjcmVhdGVzIGFuZCBvd25zIGBtYXN0cmFfaW5zdGFuY2VgICh0aGUgc2FtZVxuICAgIC8vIGluc3RhbmNlLWxldmVsIHNjaGVtYSB0aGUgd29ya2Zsb3ctc25hcHNob3Qgc3RvcmUgdXNlcykgYW5kIHRoZSBpbmRleFxuICAgIC8vIGxhbmRzIHRoZXJlLiBUYWJsZSBuYW1lcyBkb24ndCBjb2xsaWRlIHdpdGggdGhlIHN0b3JhZ2UgdGFibGVzLlxuICAgIHNjaGVtYU5hbWU6IFwibWFzdHJhX2luc3RhbmNlXCIsXG4gICAgaG9zdDogXCItMVwiLFxuICAgIHBvcnQ6IC0xLFxuICAgIGRhdGFiYXNlOiBcIl9cIixcbiAgICB1c2VyOiBcIl9cIixcbiAgICBwYXNzd29yZDogXCJfXCIsXG4gIH0pO1xuICBjb25zdCBwbGFjZWhvbGRlciA9IHZlY3Rvci5wb29sO1xuICB2ZWN0b3IucG9vbCA9IHBvb2w7XG4gIHZvaWQgcGxhY2Vob2xkZXIuZW5kKCkuY2F0Y2goKCkgPT4gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIHZlY3Rvcjtcbn1cblxuLyoqIFBlci1hZ2VudCBkZWRpY2F0ZWQgYFBnVmVjdG9yYCAocmFyZTsgb3B0LWluIHZpYSBvYmplY3Qgb3ZlcnJpZGUpLiAqL1xuZnVuY3Rpb24gYnVpbGRQZ1ZlY3RvcihzZXR0aW5nOiBNYXN0cmFNZW1vcnlDb25maWdPdmVycmlkZSk6IFBnVmVjdG9yIHtcbiAgcmV0dXJuIG5ldyBQZ1ZlY3RvcihcbiAgICB3aXRoSWQoc2V0dGluZywgYHBnLXZlY3Rvcl9fJHtoYXNoLmlkKCl9YCkgYXMgQ29uc3RydWN0b3JQYXJhbWV0ZXJzPHR5cGVvZiBQZ1ZlY3Rvcj5bMF0sXG4gICk7XG59XG5cbi8qKiBUcnVlIHdoZW4gdGhpcyBzZXR0aW5nIHJlcXVpcmVzIHRoZSBzaGFyZWQgTGFrZWJhc2UgcG9vbC4gKi9cbmZ1bmN0aW9uIHNldHRpbmdOZWVkc1NoYXJlZFBvb2woc2V0dGluZzogU3RvcmFnZVNldHRpbmcgfCBNZW1vcnlTZXR0aW5nIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiBzZXR0aW5nID09PSB0cnVlO1xufVxuXG4vKiogV2FsayB0aGUgdGhyZWUgc2hhcGVzIG9mIGBjb25maWcuYWdlbnRzYCBpbnRvIGEgZmxhdCBsaXN0LiAqL1xuZnVuY3Rpb24gY29sbGVjdEFnZW50RGVmaW5pdGlvbnMoY29uZmlnOiBNYXN0cmFQbHVnaW5Db25maWcpOiBNYXN0cmFBZ2VudERlZmluaXRpb25bXSB7XG4gIGNvbnN0IGFnZW50cyA9IGNvbmZpZy5hZ2VudHM7XG4gIGlmICghYWdlbnRzKSByZXR1cm4gW107XG4gIGlmIChBcnJheS5pc0FycmF5KGFnZW50cykpIHJldHVybiBhZ2VudHM7XG4gIGlmICh0eXBlb2YgKGFnZW50cyBhcyBNYXN0cmFBZ2VudERlZmluaXRpb24pLmluc3RydWN0aW9ucyA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiBbYWdlbnRzIGFzIE1hc3RyYUFnZW50RGVmaW5pdGlvbl07XG4gIH1cbiAgcmV0dXJuIE9iamVjdC52YWx1ZXMoYWdlbnRzIGFzIFJlY29yZDxzdHJpbmcsIE1hc3RyYUFnZW50RGVmaW5pdGlvbj4pO1xufVxuXG4vKiogRmlsbCBpbiBhIGRlZmF1bHQgYGlkYCB3aGVuIHRoZSBjYWxsZXIgZGlkbid0IHN1cHBseSBvbmUuICovXG5mdW5jdGlvbiB3aXRoSWQ8VCBleHRlbmRzIHsgaWQ/OiBzdHJpbmcgfT4odmFsdWU6IFQsIGZhbGxiYWNrOiBzdHJpbmcpOiBUIHtcbiAgcmV0dXJuIHZhbHVlLmlkID8gdmFsdWUgOiB7IC4uLnZhbHVlLCBpZDogZmFsbGJhY2sgfTtcbn1cbiJdfQ==
|
package/package.json
CHANGED
|
@@ -31,18 +31,18 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@databricks/appkit": "^0.43.0",
|
|
33
33
|
"@databricks/sdk-experimental": "^0.17.0",
|
|
34
|
-
"@dbx-tools/appkit": "0.6.
|
|
35
|
-
"@dbx-tools/core": "0.6.
|
|
36
|
-
"@dbx-tools/databricks": "0.6.
|
|
37
|
-
"@dbx-tools/fs": "0.6.
|
|
38
|
-
"@dbx-tools/genie": "0.6.
|
|
39
|
-
"@dbx-tools/model": "0.6.
|
|
40
|
-
"@dbx-tools/path": "0.6.
|
|
41
|
-
"@dbx-tools/shared-core": "0.6.
|
|
42
|
-
"@dbx-tools/shared-fs": "0.6.
|
|
43
|
-
"@dbx-tools/shared-genie": "0.6.
|
|
44
|
-
"@dbx-tools/shared-mastra": "0.6.
|
|
45
|
-
"@dbx-tools/shared-model": "0.6.
|
|
34
|
+
"@dbx-tools/appkit": "0.6.71",
|
|
35
|
+
"@dbx-tools/core": "0.6.71",
|
|
36
|
+
"@dbx-tools/databricks": "0.6.71",
|
|
37
|
+
"@dbx-tools/fs": "0.6.71",
|
|
38
|
+
"@dbx-tools/genie": "0.6.71",
|
|
39
|
+
"@dbx-tools/model": "0.6.71",
|
|
40
|
+
"@dbx-tools/path": "0.6.71",
|
|
41
|
+
"@dbx-tools/shared-core": "0.6.71",
|
|
42
|
+
"@dbx-tools/shared-fs": "0.6.71",
|
|
43
|
+
"@dbx-tools/shared-genie": "0.6.71",
|
|
44
|
+
"@dbx-tools/shared-mastra": "0.6.71",
|
|
45
|
+
"@dbx-tools/shared-model": "0.6.71",
|
|
46
46
|
"@mastra/ai-sdk": "^1.6.0",
|
|
47
47
|
"@mastra/core": "^1.47.0",
|
|
48
48
|
"@mastra/express": "^1.4.2",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"./package.json": "./package.json"
|
|
72
72
|
}
|
|
73
73
|
},
|
|
74
|
-
"version": "0.6.
|
|
74
|
+
"version": "0.6.71",
|
|
75
75
|
"types": "./lib/index.d.ts",
|
|
76
76
|
"type": "module",
|
|
77
77
|
"exports": {
|
package/src/memory.ts
CHANGED
|
@@ -8,7 +8,10 @@
|
|
|
8
8
|
* **per-agent** namespacing via {@link agentStorageSchemaName} so
|
|
9
9
|
* conversation history stays isolated between agents in the same
|
|
10
10
|
* database. `PostgresStore` auto-creates the schema with
|
|
11
|
-
* `CREATE SCHEMA IF NOT EXISTS` on init.
|
|
11
|
+
* `CREATE SCHEMA IF NOT EXISTS` on init. A failed migration (common on
|
|
12
|
+
* Lakebase when the connecting role is not the table owner) is logged
|
|
13
|
+
* and skipped via {@link withSoftStorageInit} so existing tables keep
|
|
14
|
+
* serving instead of retrying DDL on every request.
|
|
12
15
|
* - **Memory** (semantic recall via `PgVector`): defaults to a single
|
|
13
16
|
* **shared** instance across every agent. Cross-agent recall on one
|
|
14
17
|
* index is almost always what users want; opt into per-agent recall
|
|
@@ -30,7 +33,7 @@
|
|
|
30
33
|
*/
|
|
31
34
|
|
|
32
35
|
import { getUsernameWithApiLookup } from "@databricks/appkit";
|
|
33
|
-
import { hash, log } from "@dbx-tools/shared-core";
|
|
36
|
+
import { error, hash, log } from "@dbx-tools/shared-core";
|
|
34
37
|
import { fastembed } from "@mastra/fastembed";
|
|
35
38
|
import { Memory } from "@mastra/memory";
|
|
36
39
|
import { PgVector, PostgresStore } from "@mastra/pg";
|
|
@@ -43,6 +46,47 @@ import { summaryModel, TITLE_INSTRUCTIONS } from "./summarize.ts";
|
|
|
43
46
|
|
|
44
47
|
const logger = log.logger("mastra/memory");
|
|
45
48
|
|
|
49
|
+
/** Whether `LOG_LEVEL` is currently at or below debug. */
|
|
50
|
+
function isDebugEnabled(): boolean {
|
|
51
|
+
return log.isLevelEnabled("debug");
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Soften {@link PostgresStore.init} so a failed migration (e.g. Lakebase
|
|
56
|
+
* `must be owner of table …` on `ALTER`) is logged once instead of rethrown
|
|
57
|
+
* on every storage call.
|
|
58
|
+
*
|
|
59
|
+
* Mastra's `augmentWithInit` retries init forever when it throws, so the
|
|
60
|
+
* only way to keep serving against an already-usable schema is to treat
|
|
61
|
+
* migration failure as success and mark the store initialized.
|
|
62
|
+
*/
|
|
63
|
+
export function withSoftStorageInit(store: PostgresStore): PostgresStore {
|
|
64
|
+
const soft = store as unknown as {
|
|
65
|
+
init: () => Promise<void>;
|
|
66
|
+
id: string;
|
|
67
|
+
schema?: string;
|
|
68
|
+
isInitialized: boolean;
|
|
69
|
+
};
|
|
70
|
+
const originalInit = soft.init.bind(soft);
|
|
71
|
+
soft.init = async () => {
|
|
72
|
+
try {
|
|
73
|
+
await originalInit();
|
|
74
|
+
} catch (err) {
|
|
75
|
+
if (isDebugEnabled()) {
|
|
76
|
+
logger.error("mastra storage migration failed", err);
|
|
77
|
+
} else {
|
|
78
|
+
logger.warn("mastra storage migration failed", {
|
|
79
|
+
error: error.errorMessage(err),
|
|
80
|
+
storeId: soft.id,
|
|
81
|
+
schema: soft.schema,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
soft.isInitialized = true;
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
return store;
|
|
88
|
+
}
|
|
89
|
+
|
|
46
90
|
/**
|
|
47
91
|
* Build a dedicated **service-principal** Lakebase pool for Mastra
|
|
48
92
|
* memory from the lakebase plugin's resolved SP pg config.
|
|
@@ -129,15 +173,21 @@ export class MemoryBuilder {
|
|
|
129
173
|
const setting = this.config.storage;
|
|
130
174
|
if (!setting) return undefined;
|
|
131
175
|
if (typeof setting === "object") {
|
|
132
|
-
return
|
|
133
|
-
|
|
176
|
+
return withSoftStorageInit(
|
|
177
|
+
new PostgresStore(
|
|
178
|
+
withId(setting, "mastra-store__instance") as ConstructorParameters<
|
|
179
|
+
typeof PostgresStore
|
|
180
|
+
>[0],
|
|
181
|
+
),
|
|
134
182
|
);
|
|
135
183
|
}
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
184
|
+
return withSoftStorageInit(
|
|
185
|
+
new PostgresStore({
|
|
186
|
+
id: "mastra-store__instance",
|
|
187
|
+
schemaName: "mastra_instance",
|
|
188
|
+
pool: this.servicePrincipalPool,
|
|
189
|
+
}),
|
|
190
|
+
);
|
|
141
191
|
}
|
|
142
192
|
|
|
143
193
|
/**
|
|
@@ -192,17 +242,23 @@ export class MemoryBuilder {
|
|
|
192
242
|
private buildStorage(agentId: string, setting: StorageSetting): PostgresStore | undefined {
|
|
193
243
|
if (!setting) return undefined;
|
|
194
244
|
if (typeof setting === "boolean") {
|
|
195
|
-
return
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
245
|
+
return withSoftStorageInit(
|
|
246
|
+
new PostgresStore({
|
|
247
|
+
id: `mastra-store__${agentId}`,
|
|
248
|
+
schemaName: agentStorageSchemaName(agentId),
|
|
249
|
+
pool: this.servicePrincipalPool,
|
|
250
|
+
}),
|
|
251
|
+
);
|
|
200
252
|
}
|
|
201
253
|
// Cast: `withId` guarantees `id` is set, but the distributive
|
|
202
254
|
// Omit + `id?: string` shape doesn't structurally narrow to the
|
|
203
255
|
// discriminated union members. Runtime shape is identical.
|
|
204
|
-
return
|
|
205
|
-
|
|
256
|
+
return withSoftStorageInit(
|
|
257
|
+
new PostgresStore(
|
|
258
|
+
withId(setting, `mastra-store__${agentId}`) as ConstructorParameters<
|
|
259
|
+
typeof PostgresStore
|
|
260
|
+
>[0],
|
|
261
|
+
),
|
|
206
262
|
);
|
|
207
263
|
}
|
|
208
264
|
|