@dbx-tools/model 0.6.223 → 0.6.225
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 +15 -5
- package/index.ts +2 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +3 -2
- package/lib/src/policy.d.ts +10 -0
- package/lib/src/policy.js +15 -0
- package/lib/src/resolve.d.ts +14 -17
- package/lib/src/resolve.js +79 -96
- package/lib/src/serving.js +6 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/policy.ts +21 -0
- package/src/resolve.ts +92 -96
- package/src/serving.ts +5 -0
package/README.md
CHANGED
|
@@ -14,7 +14,8 @@ Browser-safe request/result schemas and endpoint classification types live in
|
|
|
14
14
|
Key features:
|
|
15
15
|
|
|
16
16
|
- Lists Databricks Model Serving endpoints through the SDK and normalizes them
|
|
17
|
-
into a stable summary shape
|
|
17
|
+
into a stable summary shape with Rust-derived family and reasoning-effort
|
|
18
|
+
metadata.
|
|
18
19
|
- Classifies endpoints into chat-thinking, chat-balanced, chat-fast, and
|
|
19
20
|
embedding classes using Foundation Model API scores and family heuristics.
|
|
20
21
|
- Resolves loose user input such as `"sonnet"` or `"chat fast"` to a concrete
|
|
@@ -69,6 +70,11 @@ console.log(selected.modelId, selected.source);
|
|
|
69
70
|
`selectModel()` is the high-level helper for agents and CLIs. It reads the live
|
|
70
71
|
catalogue, applies fuzzy matching when an explicit string is present, then
|
|
71
72
|
returns a single `modelId` plus a source label explaining why that endpoint won.
|
|
73
|
+
Set `liveOnly: true` for an unpinned production default that must select the
|
|
74
|
+
highest-ranked currently available endpoint and must not fall through to an
|
|
75
|
+
offline static id when the catalogue has no match.
|
|
76
|
+
With no explicit id or class, automatic selection prefers the highest-ranked
|
|
77
|
+
live GPT family member, then falls back to the highest-ranked live chat model.
|
|
72
78
|
|
|
73
79
|
The `source` label is useful for logs and debug UIs. It distinguishes explicit
|
|
74
80
|
matches from class-based selection, environment defaults, and fallback results,
|
|
@@ -89,7 +95,10 @@ const ranked = await resolve.searchModels(client, host, {
|
|
|
89
95
|
|
|
90
96
|
Use `searchModels()` for UI pickers and debug routes. It returns ranked models
|
|
91
97
|
with match scores and endpoint summaries, using the same fuzzy threshold and
|
|
92
|
-
class ceiling logic as `selectModel()`.
|
|
98
|
+
class ceiling logic as `selectModel()`. Both delegate catalogue ranking to the
|
|
99
|
+
generated [`@dbx-tools/model-rs`](../model-rs) binding, so Node and the Rust
|
|
100
|
+
model proxy use one fuzzy scorer, family-version order, variant preference, and
|
|
101
|
+
class policy.
|
|
93
102
|
|
|
94
103
|
## Work With A Held Catalogue
|
|
95
104
|
|
|
@@ -100,7 +109,7 @@ When you already have endpoint summaries, use the pure resolver functions from
|
|
|
100
109
|
import { resolve, serving } from "@dbx-tools/model";
|
|
101
110
|
|
|
102
111
|
const endpoints = await serving.listServingEndpoints(client, host);
|
|
103
|
-
const ranked = resolve.
|
|
112
|
+
const ranked = resolve.lookupModels(endpoints, { search: "sonnet", limit: 3 });
|
|
104
113
|
const picked = resolve.resolveModel(endpoints, {
|
|
105
114
|
explicit: "claude sonnet",
|
|
106
115
|
modelClass: "chat-balanced",
|
|
@@ -205,13 +214,14 @@ policy decisions; fallbacks are a last resort.
|
|
|
205
214
|
|
|
206
215
|
## Modules
|
|
207
216
|
|
|
208
|
-
- `resolve` - high-level `selectModel`, ranked search, and
|
|
209
|
-
resolver functions.
|
|
217
|
+
- `resolve` - high-level `selectModel`, Rust-backed ranked search, and
|
|
218
|
+
catalogue-held resolver functions.
|
|
210
219
|
- `serving` - Databricks serving-endpoint listing, cache management, fuzzy
|
|
211
220
|
search, and endpoint-id resolution.
|
|
212
221
|
- `invoke` - serving-path constants, URL construction, and per-request auth
|
|
213
222
|
headers for calling an endpoint over raw HTTP.
|
|
214
223
|
- `classes` - model-class parsing, ordering, and class-ceiling helpers.
|
|
224
|
+
- `policy` - Rust-backed family and reasoning-effort metadata projection.
|
|
215
225
|
- `fallback` - static fallback model ids per class.
|
|
216
226
|
|
|
217
227
|
The AppKit-Mastra integration uses this package through
|
package/index.ts
CHANGED
|
@@ -3,10 +3,11 @@
|
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
|
|
5
5
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/model";
|
|
6
|
-
export const PACKAGE_VERSION = "0.6.
|
|
6
|
+
export const PACKAGE_VERSION = "0.6.225";
|
|
7
7
|
export * as classes from "./src/classes.ts";
|
|
8
8
|
export * as fallback from "./src/fallback.ts";
|
|
9
9
|
export * as invoke from "./src/invoke.ts";
|
|
10
|
+
export * as policy from "./src/policy.ts";
|
|
10
11
|
export * as resolve from "./src/resolve.ts";
|
|
11
12
|
export * as serving from "./src/serving.ts";
|
|
12
13
|
export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER } from "./src/classes.ts";
|
package/lib/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export declare const PACKAGE_IDENTIFIER = "@dbx-tools/model";
|
|
2
|
-
export declare const PACKAGE_VERSION = "0.6.
|
|
2
|
+
export declare const PACKAGE_VERSION = "0.6.225";
|
|
3
3
|
export * as classes from "./src/classes.ts";
|
|
4
4
|
export * as fallback from "./src/fallback.ts";
|
|
5
5
|
export * as invoke from "./src/invoke.ts";
|
|
6
|
+
export * as policy from "./src/policy.ts";
|
|
6
7
|
export * as resolve from "./src/resolve.ts";
|
|
7
8
|
export * as serving from "./src/serving.ts";
|
|
8
9
|
export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER } from "./src/classes.ts";
|
package/lib/index.js
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
// Regenerated from the exporting modules in ./src.
|
|
3
3
|
// Hand edits are overwritten on the next watch; this file is read-only.
|
|
4
4
|
export const PACKAGE_IDENTIFIER = "@dbx-tools/model";
|
|
5
|
-
export const PACKAGE_VERSION = "0.6.
|
|
5
|
+
export const PACKAGE_VERSION = "0.6.225";
|
|
6
6
|
export * as classes from "./src/classes.js";
|
|
7
7
|
export * as fallback from "./src/fallback.js";
|
|
8
8
|
export * as invoke from "./src/invoke.js";
|
|
9
|
+
export * as policy from "./src/policy.js";
|
|
9
10
|
export * as resolve from "./src/resolve.js";
|
|
10
11
|
export * as serving from "./src/serving.js";
|
|
11
12
|
export { CHAT_CLASS_ORDER, MODEL_CLASS_ORDER } from "./src/classes.js";
|
|
12
13
|
export { FALLBACK_MODEL_IDS } from "./src/fallback.js";
|
|
13
14
|
export { INVOCATIONS_SUFFIX, RESPONSES_PATH, OPEN_RESPONSES_PATH, CHAT_COMPLETIONS_PATH } from "./src/invoke.js";
|
|
14
15
|
export { DEFAULT_MODEL_CACHE_TTL_MS, DEFAULT_FUZZY_THRESHOLD } from "./src/serving.js";
|
|
15
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
16
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwyQ0FBMkM7QUFDM0MsbURBQW1EO0FBQ25ELHdFQUF3RTtBQUV4RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQztBQUNyRCxNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsU0FBUyxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxPQUFPLE1BQU0sa0JBQWtCLENBQUM7QUFDNUMsT0FBTyxLQUFLLFFBQVEsTUFBTSxtQkFBbUIsQ0FBQztBQUM5QyxPQUFPLEtBQUssTUFBTSxNQUFNLGlCQUFpQixDQUFDO0FBQzFDLE9BQU8sS0FBSyxNQUFNLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxLQUFLLE9BQU8sTUFBTSxrQkFBa0IsQ0FBQztBQUM1QyxPQUFPLEtBQUssT0FBTyxNQUFNLGtCQUFrQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUdqSCxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEdFTkVSQVRFRCBieSBwcm9qZW4gd2F0Y2ggLSBETyBOT1QgRURJVC5cbi8vIFJlZ2VuZXJhdGVkIGZyb20gdGhlIGV4cG9ydGluZyBtb2R1bGVzIGluIC4vc3JjLlxuLy8gSGFuZCBlZGl0cyBhcmUgb3ZlcndyaXR0ZW4gb24gdGhlIG5leHQgd2F0Y2g7IHRoaXMgZmlsZSBpcyByZWFkLW9ubHkuXG5cbmV4cG9ydCBjb25zdCBQQUNLQUdFX0lERU5USUZJRVIgPSBcIkBkYngtdG9vbHMvbW9kZWxcIjtcbmV4cG9ydCBjb25zdCBQQUNLQUdFX1ZFUlNJT04gPSBcIjAuNi4yMjVcIjtcbmV4cG9ydCAqIGFzIGNsYXNzZXMgZnJvbSBcIi4vc3JjL2NsYXNzZXMudHNcIjtcbmV4cG9ydCAqIGFzIGZhbGxiYWNrIGZyb20gXCIuL3NyYy9mYWxsYmFjay50c1wiO1xuZXhwb3J0ICogYXMgaW52b2tlIGZyb20gXCIuL3NyYy9pbnZva2UudHNcIjtcbmV4cG9ydCAqIGFzIHBvbGljeSBmcm9tIFwiLi9zcmMvcG9saWN5LnRzXCI7XG5leHBvcnQgKiBhcyByZXNvbHZlIGZyb20gXCIuL3NyYy9yZXNvbHZlLnRzXCI7XG5leHBvcnQgKiBhcyBzZXJ2aW5nIGZyb20gXCIuL3NyYy9zZXJ2aW5nLnRzXCI7XG5leHBvcnQgeyBDSEFUX0NMQVNTX09SREVSLCBNT0RFTF9DTEFTU19PUkRFUiB9IGZyb20gXCIuL3NyYy9jbGFzc2VzLnRzXCI7XG5leHBvcnQgeyBGQUxMQkFDS19NT0RFTF9JRFMgfSBmcm9tIFwiLi9zcmMvZmFsbGJhY2sudHNcIjtcbmV4cG9ydCB7IElOVk9DQVRJT05TX1NVRkZJWCwgUkVTUE9OU0VTX1BBVEgsIE9QRU5fUkVTUE9OU0VTX1BBVEgsIENIQVRfQ09NUExFVElPTlNfUEFUSCB9IGZyb20gXCIuL3NyYy9pbnZva2UudHNcIjtcbmV4cG9ydCB0eXBlIHsgQXV0aGVudGljYXRpbmdDbGllbnRMaWtlIH0gZnJvbSBcIi4vc3JjL2ludm9rZS50c1wiO1xuZXhwb3J0IHR5cGUgeyBSZXNvbHZlTW9kZWxJbnB1dCwgUmVzb2x2ZWRNb2RlbFNlbGVjdGlvbiwgU2VsZWN0TW9kZWxJbnB1dCwgU2VhcmNoTW9kZWxzSW5wdXQgfSBmcm9tIFwiLi9zcmMvcmVzb2x2ZS50c1wiO1xuZXhwb3J0IHsgREVGQVVMVF9NT0RFTF9DQUNIRV9UVExfTVMsIERFRkFVTFRfRlVaWllfVEhSRVNIT0xEIH0gZnJvbSBcIi4vc3JjL3NlcnZpbmcudHNcIjtcbmV4cG9ydCB0eXBlIHsgV29ya3NwYWNlQ2xpZW50TGlrZSwgTGlzdFNlcnZpbmdFbmRwb2ludHNPcHRpb25zLCBSZXNvbHZlZE1vZGVsLCBSZXNvbHZlTW9kZWxPcHRpb25zLCBTY29yZWRFbmRwb2ludCB9IGZyb20gXCIuL3NyYy9zZXJ2aW5nLnRzXCI7XG4iXX0=
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe model metadata projected from the Rust policy bindings.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import type { ReasoningEffort } from "@dbx-tools/shared-model";
|
|
7
|
+
/** Return the normalized family parsed by the Rust model-name policy. */
|
|
8
|
+
export declare function modelFamily(name: string): string | undefined;
|
|
9
|
+
/** Return the reasoning efforts accepted by a model family. */
|
|
10
|
+
export declare function modelReasoningEfforts(name: string): ReasoningEffort[];
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe model metadata projected from the Rust policy bindings.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
import { modelFamily as modelFamilyWithRust, reasoningEffortNamesByFamily, } from "@dbx-tools/model-rs";
|
|
7
|
+
/** Return the normalized family parsed by the Rust model-name policy. */
|
|
8
|
+
export function modelFamily(name) {
|
|
9
|
+
return modelFamilyWithRust(name);
|
|
10
|
+
}
|
|
11
|
+
/** Return the reasoning efforts accepted by a model family. */
|
|
12
|
+
export function modelReasoningEfforts(name) {
|
|
13
|
+
return reasoningEffortNamesByFamily(name);
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3BvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7OztHQUlHO0FBRUgsT0FBTyxFQUNMLFdBQVcsSUFBSSxtQkFBbUIsRUFDbEMsNEJBQTRCLEdBQzdCLE1BQU0scUJBQXFCLENBQUM7QUFHN0IseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxXQUFXLENBQUMsSUFBWTtJQUN0QyxPQUFPLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRCwrREFBK0Q7QUFDL0QsTUFBTSxVQUFVLHFCQUFxQixDQUFDLElBQVk7SUFDaEQsT0FBTyw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBCcm93c2VyLXNhZmUgbW9kZWwgbWV0YWRhdGEgcHJvamVjdGVkIGZyb20gdGhlIFJ1c3QgcG9saWN5IGJpbmRpbmdzLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQge1xuICBtb2RlbEZhbWlseSBhcyBtb2RlbEZhbWlseVdpdGhSdXN0LFxuICByZWFzb25pbmdFZmZvcnROYW1lc0J5RmFtaWx5LFxufSBmcm9tIFwiQGRieC10b29scy9tb2RlbC1yc1wiO1xuaW1wb3J0IHR5cGUgeyBSZWFzb25pbmdFZmZvcnQgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWxcIjtcblxuLyoqIFJldHVybiB0aGUgbm9ybWFsaXplZCBmYW1pbHkgcGFyc2VkIGJ5IHRoZSBSdXN0IG1vZGVsLW5hbWUgcG9saWN5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsRmFtaWx5KG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBtb2RlbEZhbWlseVdpdGhSdXN0KG5hbWUpO1xufVxuXG4vKiogUmV0dXJuIHRoZSByZWFzb25pbmcgZWZmb3J0cyBhY2NlcHRlZCBieSBhIG1vZGVsIGZhbWlseS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb2RlbFJlYXNvbmluZ0VmZm9ydHMobmFtZTogc3RyaW5nKTogUmVhc29uaW5nRWZmb3J0W10ge1xuICByZXR1cm4gcmVhc29uaW5nRWZmb3J0TmFtZXNCeUZhbWlseShuYW1lKTtcbn1cbiJdfQ==
|
package/lib/src/resolve.d.ts
CHANGED
|
@@ -53,6 +53,12 @@ export interface ResolveModelInput {
|
|
|
53
53
|
* the auto-classified catalogue.
|
|
54
54
|
*/
|
|
55
55
|
fallbacks?: readonly string[];
|
|
56
|
+
/**
|
|
57
|
+
* Refuse the static offline floor when the live catalogue has no match.
|
|
58
|
+
* Use for unpinned defaults that must always name a currently available
|
|
59
|
+
* endpoint.
|
|
60
|
+
*/
|
|
61
|
+
liveOnly?: boolean;
|
|
56
62
|
}
|
|
57
63
|
/** Outcome of {@link resolveModel}: the chosen id plus how it was reached. */
|
|
58
64
|
export interface ResolvedModelSelection {
|
|
@@ -72,20 +78,10 @@ export interface SearchModelsInput extends ModelQuery {
|
|
|
72
78
|
/**
|
|
73
79
|
* Rank the live catalogue against a {@link ModelQuery}, best-first.
|
|
74
80
|
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* {@link classify.classifyEndpoints}. Ranking is **match then class**:
|
|
80
|
-
*
|
|
81
|
-
* 1. With a `search`, only endpoints matching it survive, ordered by match
|
|
82
|
-
* distance (bucketed via {@link matchBucket} so near-identical scores tie),
|
|
83
|
-
* then by version, preferred model variant, class (more capable first), and
|
|
84
|
-
* the stable within-class rank.
|
|
85
|
-
* 2. Without a `search`, the class-then-rank candidate order stands.
|
|
86
|
-
*
|
|
87
|
-
* A `limit` truncates the result. Returns `[]` when nothing is eligible or
|
|
88
|
-
* matches - callers layer their own fallback.
|
|
81
|
+
* Rust owns classification, fuzzy scoring, family-version ordering, preferred
|
|
82
|
+
* variants, class ceilings, tool filtering, and result limiting. Node retains
|
|
83
|
+
* the caller's endpoint objects so fields outside the ranking contract remain
|
|
84
|
+
* available unchanged.
|
|
89
85
|
*/
|
|
90
86
|
export declare function lookupModels(endpoints: readonly ServingEndpointSummary[], query?: ModelQuery): RankedModel[];
|
|
91
87
|
/**
|
|
@@ -150,9 +146,10 @@ export declare function selectModel(client: WorkspaceClientLike, host: string, i
|
|
|
150
146
|
* fuzzy-ranked within the (optional) class ceiling and the best taken,
|
|
151
147
|
* falling back to the input verbatim when nothing matches.
|
|
152
148
|
* 2. **No explicit ask**: an operator-pinned `fallback` that exists in the live
|
|
153
|
-
* catalogue wins first
|
|
154
|
-
*
|
|
155
|
-
*
|
|
149
|
+
* catalogue wins first. A class request ranks within that ceiling. A
|
|
150
|
+
* general request prefers the highest-ranked live GPT, then any ranked live
|
|
151
|
+
* chat model. The static {@link FALLBACK_MODEL_IDS} floor is used only when
|
|
152
|
+
* the catalogue yields nothing in range.
|
|
156
153
|
*/
|
|
157
154
|
export declare function resolveModel(endpoints: readonly ServingEndpointSummary[], input?: ResolveModelInput): ResolvedModelSelection;
|
|
158
155
|
export {};
|
package/lib/src/resolve.js
CHANGED
|
@@ -20,106 +20,80 @@
|
|
|
20
20
|
* @module
|
|
21
21
|
*/
|
|
22
22
|
import { object } from "@dbx-tools/shared-core";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
23
|
+
import { ModelClass as ModelRsModelClass, rankModels as rankModelsWithRust, } from "@dbx-tools/model-rs";
|
|
24
|
+
import { classify, model, } from "@dbx-tools/shared-model";
|
|
25
25
|
import { FALLBACK_MODEL_IDS, modelsForClass } from "./fallback.js";
|
|
26
|
-
import { listServingEndpoints,
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
]);
|
|
36
|
-
/**
|
|
37
|
-
* Round a Fuse score to the display precision so version siblings that match a
|
|
38
|
-
* token identically (e.g. `opus-4-7` vs `opus-4-8` for the query `"opus"`) tie
|
|
39
|
-
* on match and let the class / within-class rank decide - which is what
|
|
40
|
-
* surfaces the newer, higher-quality sibling.
|
|
41
|
-
*/
|
|
42
|
-
function matchBucket(score) {
|
|
43
|
-
return Math.round((score ?? 0) * 1000);
|
|
44
|
-
}
|
|
45
|
-
function modelVariantRank(name) {
|
|
46
|
-
if (!/(?:^|[-_.])gpt(?:[-_.]|$)/i.test(name))
|
|
47
|
-
return 2;
|
|
48
|
-
if (/(?:^|[-_.])sol(?:[-_.]|$)/i.test(name))
|
|
49
|
-
return 0;
|
|
50
|
-
if (/(?:^|[-_.])luna(?:[-_.]|$)/i.test(name))
|
|
51
|
-
return 1;
|
|
52
|
-
return 2;
|
|
53
|
-
}
|
|
26
|
+
import { listServingEndpoints, } from "./serving.js";
|
|
27
|
+
/** Preferred live family for an unconfigured general-purpose chat default. */
|
|
28
|
+
const DEFAULT_MODEL_FAMILY_SEARCH = "gpt";
|
|
29
|
+
const MODEL_CLASS_TO_RS = {
|
|
30
|
+
[model.ModelClass.ChatThinking]: ModelRsModelClass.ChatThinking,
|
|
31
|
+
[model.ModelClass.ChatBalanced]: ModelRsModelClass.ChatBalanced,
|
|
32
|
+
[model.ModelClass.ChatFast]: ModelRsModelClass.ChatFast,
|
|
33
|
+
[model.ModelClass.Embedding]: ModelRsModelClass.Embedding,
|
|
34
|
+
};
|
|
54
35
|
/**
|
|
55
36
|
* Rank the live catalogue against a {@link ModelQuery}, best-first.
|
|
56
37
|
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* {@link classify.classifyEndpoints}. Ranking is **match then class**:
|
|
62
|
-
*
|
|
63
|
-
* 1. With a `search`, only endpoints matching it survive, ordered by match
|
|
64
|
-
* distance (bucketed via {@link matchBucket} so near-identical scores tie),
|
|
65
|
-
* then by version, preferred model variant, class (more capable first), and
|
|
66
|
-
* the stable within-class rank.
|
|
67
|
-
* 2. Without a `search`, the class-then-rank candidate order stands.
|
|
68
|
-
*
|
|
69
|
-
* A `limit` truncates the result. Returns `[]` when nothing is eligible or
|
|
70
|
-
* matches - callers layer their own fallback.
|
|
38
|
+
* Rust owns classification, fuzzy scoring, family-version ordering, preferred
|
|
39
|
+
* variants, class ceilings, tool filtering, and result limiting. Node retains
|
|
40
|
+
* the caller's endpoint objects so fields outside the ranking contract remain
|
|
41
|
+
* available unchanged.
|
|
71
42
|
*/
|
|
72
43
|
export function lookupModels(endpoints, query = {}) {
|
|
73
|
-
const
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
for (const modelClass of eligible) {
|
|
79
|
-
for (const endpoint of classified[modelClass]) {
|
|
80
|
-
if (query.requiresTools && !classify.endpointCapabilities(endpoint).tools)
|
|
81
|
-
continue;
|
|
82
|
-
candidates.push({ endpoint, modelClass });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
const search = query.search?.trim();
|
|
86
|
-
let ranked;
|
|
87
|
-
if (search) {
|
|
88
|
-
const gptFamilySearch = search.toLowerCase() === "gpt";
|
|
89
|
-
const versionedFamilySearch = VERSIONED_FAMILY_SEARCHES.has(search.toLowerCase());
|
|
90
|
-
const scores = new Map();
|
|
91
|
-
for (const match of searchServingEndpoints(search, candidates.map((c) => c.endpoint), query.threshold !== undefined ? { threshold: query.threshold } : {})) {
|
|
92
|
-
scores.set(match.endpoint.name, match.score);
|
|
44
|
+
const endpointsByName = new Map(endpoints.map((endpoint) => [endpoint.name, endpoint]));
|
|
45
|
+
return rankModelsWithRust(endpoints.map(toModelRsEndpoint), toModelRsQuery(query)).map((ranked) => {
|
|
46
|
+
const endpoint = endpointsByName.get(ranked.endpoint.name);
|
|
47
|
+
if (!endpoint) {
|
|
48
|
+
throw new Error(`Rust model ranking returned unknown endpoint "${ranked.endpoint.name}"`);
|
|
93
49
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
50
|
+
return {
|
|
51
|
+
endpoint,
|
|
52
|
+
modelClass: fromModelRsClass(ranked.modelClass),
|
|
53
|
+
...(ranked.score !== undefined ? { score: ranked.score } : {}),
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/** Convert a public model query to the generated Rust ranking contract. */
|
|
58
|
+
function toModelRsQuery(query) {
|
|
59
|
+
return {
|
|
60
|
+
search: query.search,
|
|
61
|
+
modelClass: query.modelClass === undefined ? undefined : MODEL_CLASS_TO_RS[query.modelClass],
|
|
62
|
+
requiresTools: query.requiresTools ?? false,
|
|
63
|
+
includeDeprecated: false,
|
|
64
|
+
limit: query.limit,
|
|
65
|
+
threshold: query.threshold,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/** Convert a discovered endpoint to the generated Rust ranking contract. */
|
|
69
|
+
function toModelRsEndpoint(endpoint) {
|
|
70
|
+
return {
|
|
71
|
+
name: endpoint.name,
|
|
72
|
+
displayName: endpoint.displayName,
|
|
73
|
+
task: endpoint.task,
|
|
74
|
+
state: endpoint.state,
|
|
75
|
+
description: endpoint.description,
|
|
76
|
+
supportsTools: endpoint.supportsTools,
|
|
77
|
+
profile: endpoint.profile,
|
|
78
|
+
modelClass: endpoint.class === undefined ? undefined : MODEL_CLASS_TO_RS[endpoint.class],
|
|
79
|
+
serviceNames: new Map(Object.entries(endpoint.serviceNames ?? {})),
|
|
80
|
+
modelServiceName: endpoint.modelServiceName,
|
|
81
|
+
reasoningEfforts: [],
|
|
82
|
+
status: { deprecated: endpoint.status?.deprecated ?? false },
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Convert a generated Rust class to the browser-safe public enum. */
|
|
86
|
+
function fromModelRsClass(modelClass) {
|
|
87
|
+
switch (modelClass) {
|
|
88
|
+
case ModelRsModelClass.ChatThinking:
|
|
89
|
+
return model.ModelClass.ChatThinking;
|
|
90
|
+
case ModelRsModelClass.ChatBalanced:
|
|
91
|
+
return model.ModelClass.ChatBalanced;
|
|
92
|
+
case ModelRsModelClass.ChatFast:
|
|
93
|
+
return model.ModelClass.ChatFast;
|
|
94
|
+
case ModelRsModelClass.Embedding:
|
|
95
|
+
return model.ModelClass.Embedding;
|
|
121
96
|
}
|
|
122
|
-
return query.limit !== undefined ? ranked.slice(0, Math.max(0, query.limit)) : ranked;
|
|
123
97
|
}
|
|
124
98
|
/**
|
|
125
99
|
* Collapse {@link lookupModels} to a single id: the closest endpoint to `search`
|
|
@@ -209,9 +183,10 @@ export async function selectModel(client, host, input = {}) {
|
|
|
209
183
|
* fuzzy-ranked within the (optional) class ceiling and the best taken,
|
|
210
184
|
* falling back to the input verbatim when nothing matches.
|
|
211
185
|
* 2. **No explicit ask**: an operator-pinned `fallback` that exists in the live
|
|
212
|
-
* catalogue wins first
|
|
213
|
-
*
|
|
214
|
-
*
|
|
186
|
+
* catalogue wins first. A class request ranks within that ceiling. A
|
|
187
|
+
* general request prefers the highest-ranked live GPT, then any ranked live
|
|
188
|
+
* chat model. The static {@link FALLBACK_MODEL_IDS} floor is used only when
|
|
189
|
+
* the catalogue yields nothing in range.
|
|
215
190
|
*/
|
|
216
191
|
export function resolveModel(endpoints, input = {}) {
|
|
217
192
|
if (input.explicit !== undefined) {
|
|
@@ -237,9 +212,17 @@ export function resolveModel(endpoints, input = {}) {
|
|
|
237
212
|
return { modelId: pinned, source: "fallback" };
|
|
238
213
|
}
|
|
239
214
|
const source = input.modelClass !== undefined ? "class" : "fallback";
|
|
215
|
+
if (input.modelClass === undefined) {
|
|
216
|
+
const [preferred] = lookupModels(endpoints, buildQuery(input, DEFAULT_MODEL_FAMILY_SEARCH));
|
|
217
|
+
if (preferred)
|
|
218
|
+
return { modelId: preferred.endpoint.name, source };
|
|
219
|
+
}
|
|
240
220
|
const [top] = lookupModels(endpoints, buildQuery(input, undefined));
|
|
241
221
|
if (top)
|
|
242
222
|
return { modelId: top.endpoint.name, source };
|
|
223
|
+
if (input.liveOnly) {
|
|
224
|
+
throw new Error("No matching live Model Serving endpoint is available");
|
|
225
|
+
}
|
|
243
226
|
// Live catalogue yielded nothing in range: walk the static floor.
|
|
244
227
|
const floorSource = input.modelClass !== undefined ? modelsForClass(input.modelClass) : (input.fallbacks ?? []);
|
|
245
228
|
const floor = object.sequence(floorSource).concat(FALLBACK_MODEL_IDS).distinct().toArray();
|
|
@@ -285,4 +268,4 @@ function pickFirstAvailable(candidates, endpoints) {
|
|
|
285
268
|
}
|
|
286
269
|
return candidates[0] ?? FALLBACK_MODEL_IDS[0];
|
|
287
270
|
}
|
|
288
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZXNvbHZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRCxPQUFPLEVBQ0wsUUFBUSxHQUtULE1BQU0seUJBQXlCLENBQUM7QUFFakMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3JGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkUsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixzQkFBc0IsR0FJdkIsTUFBTSxjQUFjLENBQUM7QUFJdEIsTUFBTSx5QkFBeUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUN4QyxRQUFRO0lBQ1IsUUFBUTtJQUNSLE9BQU87SUFDUCxLQUFLO0lBQ0wsS0FBSztJQUNMLE9BQU87SUFDUCxNQUFNO0NBQ1AsQ0FBQyxDQUFDO0FBcURIOzs7OztHQUtHO0FBQ0gsU0FBUyxXQUFXLENBQUMsS0FBeUI7SUFDNUMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDO0FBQ3pDLENBQUM7QUFFRCxTQUFTLGdCQUFnQixDQUFDLElBQVk7SUFDcEMsSUFBSSxDQUFDLDRCQUE0QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxJQUFJLDRCQUE0QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUN0RCxJQUFJLDZCQUE2QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUN2RCxPQUFPLENBQUMsQ0FBQztBQUNYLENB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LENBQUMsQ0FBQyxFQUFFLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUN4RSxLQUFLLEVBQUUsQ0FBQztLQUNULENBQUM7QUFDSixDQUFDO0FBRUQsOEVBQThFO0FBQzlFLFNBQVMsaUJBQWlCLENBQUMsU0FBNEMsRUFBRSxPQUFlO0lBQ3RGLE1BQU0sUUFBUSxHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDLENBQUM7SUFDM0UsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoRSxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsT0FBTyxtQ0FBbUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7QUFDSCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLGtCQUFrQixDQUN6QixVQUE2QixFQUM3QixTQUE0QztJQUU1QyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN0RCxLQUFLLE1BQU0sU0FBUyxJQUFJLFVBQVUsRUFBRSxDQUFDO1FBQ25DLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUM7WUFBRSxPQUFPLFNBQVMsQ0FBQztJQUMvQyxDQUFDO0lBQ0QsT0FBTyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksa0JBQWtCLENBQUMsQ0FBQyxDQUFFLENBQUM7QUFDakQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogV29ya3NwYWNlLWF3YXJlIG1vZGVsIHNlbGVjdGlvbi5cbiAqXG4gKiBHaXZlbiBhIGNhbGxlcidzIGludGVudCAtIGEgc2VhcmNoIHN0cmluZywgYSBjYXBhYmlsaXR5IHtAbGluayBNb2RlbENsYXNzfVxuICogY2VpbGluZywgYm90aCwgb3Igbm90aGluZyAtIHRoZSB0b29sa2l0IHJldHVybnMgbWF0Y2hpbmcgZW5kcG9pbnRzIHJhbmtlZCBieVxuICogbWF0Y2ggcXVhbGl0eSB0aGVuIGNsYXNzLCBvciBjb2xsYXBzZXMgdG8gdGhlIHNpbmdsZSBiZXN0IGlkIHRoZSB3b3Jrc3BhY2VcbiAqIGFjdHVhbGx5IGhhcywgZGVncmFkaW5nIGZyb20gXCJiZXN0IGluIHJhbmdlXCIgZG93biB0byB0aGUgc3RhdGljIGZhbGxiYWNrXG4gKiBmbG9vci4gU2VsZWN0aW9uIGlzIGNoYXQtb25seTogZW1iZWRkaW5nIGVuZHBvaW50cyBzdXJmYWNlIG9ubHkgd2hlblxuICogYG1vZGVsQ2xhc3NgIGlzIGV4cGxpY2l0bHkge0BsaW5rIE1vZGVsQ2xhc3MuRW1iZWRkaW5nfS5cbiAqXG4gKiBUd28gc2hhcGVzIG9mIHNlbGVjdGlvbiwgZWFjaCBpbiBhIHB1cmUgZm9ybSAob3ZlciBhbiBlbmRwb2ludCBsaXN0IHRoZVxuICogY2FsbGVyIGFscmVhZHkgaG9sZHMpIGFuZCBhbiBJL08gd3JhcHBlciAodGhhdCBsaXN0cyBgL3NlcnZpbmctZW5kcG9pbnRzYFxuICogZmlyc3QpOiByYW5raW5nLCB3aGljaCByZXR1cm5zIGEgbWF0Y2gtIHRoZW4gY2xhc3Mtb3JkZXJlZCBsaXN0LCBhbmRcbiAqIHNpbmdsZS1zZWxlY3Rpb24sIHdoaWNoIGNvbGxhcHNlcyB0byBvbmUgaWQgcGx1cyBob3cgaXQgd2FzIHJlYWNoZWQgYW5kXG4gKiBsYXllcnMgdGhlIG9wZXJhdG9yLXBpbm5lZCBmYWxsYmFjayAvIHN0YXRpYy1mbG9vciBzYWZldHkgbmV0IG9uIHRvcC4gQSBjaGF0XG4gKiBgbW9kZWxDbGFzc2AgYWN0cyBhcyBhIGNlaWxpbmc6IHRoYXQgYmFuZCBhbmQgdGhlIGxlc3MtY2FwYWJsZSBjaGF0IGJhbmRzXG4gKiBiZWxvdyBpdCBhcmUgZWxpZ2libGUgKHNlZSB7QGxpbmsgY2xhc3Nlc0F0T3JCZWxvd30pLCBzbyBhIGBjaGF0LWJhbGFuY2VkYFxuICogYXNrIGNhbiBmYWxsIHRvIGBjaGF0LWZhc3RgIGJ1dCBuZXZlciBlc2NhbGF0ZSB0byBgY2hhdC10aGlua2luZ2AuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IG9iamVjdCB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQge1xuICBjbGFzc2lmeSxcbiAgbW9kZWwsXG4gIHR5cGUgTW9kZWxRdWVyeSxcbiAgdHlwZSBSYW5rZWRNb2RlbCxcbiAgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5LFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWxcIjtcblxuaW1wb3J0IHsgQ0hBVF9DTEFTU19PUkRFUiwgY2xhc3Nlc0F0T3JCZWxvdywgTU9ERUxfQ0xBU1NfT1JERVIgfSBmcm9tIFwiLi9jbGFzc2VzLnRzXCI7XG5pbXBvcnQgeyBGQUxMQkFDS19NT0RFTF9JRFMsIG1vZGVsc0ZvckNsYXNzIH0gZnJvbSBcIi4vZmFsbGJhY2sudHNcIjtcbmltcG9ydCB7XG4gIGxpc3RTZXJ2aW5nRW5kcG9pbnRzLFxuICBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzLFxuICB0eXBlIFJlc29sdmVkTW9kZWwsXG4gIHR5cGUgUmVzb2x2ZU1vZGVsT3B0aW9ucyxcbiAgdHlwZSBXb3Jrc3BhY2VDbGllbnRMaWtlLFxufSBmcm9tIFwiLi9zZXJ2aW5nLnRzXCI7XG5cbnR5cGUgTW9kZWxDbGFzcyA9IG1vZGVsLk1vZGVsQ2xhc3M7XG5cbmNvbnN0IFZFUlNJT05FRF9GQU1JTFlfU0VBUkNIRVMgPSBuZXcgU2V0KFtcbiAgXCJjbGF1ZGVcIixcbiAgXCJnZW1pbmlcIixcbiAgXCJnZW1tYVwiLFxuICBcImdsbVwiLFxuICBcImdwdFwiLFxuICBcImxsYW1hXCIsXG4gIFwicXdlblwiLFxuXSk7XG5cbi8qKiBDYWxsZXIgaW50ZW50IHBhc3NlZCB0byB7QGxpbmsgcmVzb2x2ZU1vZGVsfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZU1vZGVsSW5wdXQge1xuICAvKipcbiAgICogRXhwbGljaXQgbW9kZWwgaWQgLyBsb29zZSBuYW1lIChwZXItcmVxdWVzdCBvdmVycmlkZSwgYWdlbnQgLyBwbHVnaW5cbiAgICogZGVmYXVsdCwgb3IgZW52IHZhcikuIFdoZW4gc2V0IGl0IHdpbnMgb3ZlciBgbW9kZWxDbGFzc2AgYW5kIGBmYWxsYmFja3NgLlxuICAgKi9cbiAgZXhwbGljaXQ/OiBzdHJpbmc7XG4gIC8qKlxuICAgKiBGdXp6eS1tYXRjaCBhbiBgZXhwbGljaXRgIG5hbWUgYWdhaW5zdCB0aGUgbGl2ZSBjYXRhbG9ndWUgc28gbG9vc2UgbmFtZXNcbiAgICogbGlrZSBgXCJjbGF1ZGUgc29ubmV0XCJgIHJlc29sdmUuIERlZmF1bHQgYHRydWVgLiBXaGVuIGBmYWxzZWAgdGhlIGV4cGxpY2l0XG4gICAqIGlucHV0IGlzIHJldHVybmVkIHZlcmJhdGltIChEYXRhYnJpY2tzIHN1cmZhY2VzIHRoZSBjYW5vbmljYWwgNDA0IGlmIGl0XG4gICAqIGRvZXNuJ3QgZXhpc3QpLlxuICAgKi9cbiAgZnV6enk/OiBib29sZWFuO1xuICAvKiogRnVzZS5qcyB0aHJlc2hvbGQgZm9yd2FyZGVkIHRvIHRoZSBmdXp6eSBgc2VhcmNoYCBtYXRjaCAoe0BsaW5rIHNlYXJjaFNlcnZpbmdFbmRwb2ludHN9KS4gKi9cbiAgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKiogUmVxdWlyZSBhIG1vZGVsIHRoYXQgc3VwcG9ydHMgYSBjb21wbGV0ZSBmdW5jdGlvbi10b29sIHJvdW5kLXRyaXAuICovXG4gIHJlcXVpcmVzVG9vbHM/OiBib29sZWFuO1xuICAvKipcbiAgICogQ2hhdCBjYXBhYmlsaXR5IGNsYXNzIHRvIHJlc29sdmUgd2hlbiBubyBgZXhwbGljaXRgIGlkIGlzIGdpdmVuLiBUaGUgbGl2ZVxuICAgKiBjYXRhbG9ndWUgaXMgY2xhc3NpZmllZCBieSBpdHMgRm91bmRhdGlvbiBNb2RlbCBBUEkgc2NvcmVzIGFuZCB0aGUgdG9wXG4gICAqIGF2YWlsYWJsZSBtb2RlbCBpbiB0aGUgY2xhc3MgKGFuZCB0aGUgY2hhdCBiYW5kcyBiZWxvdyBpdCkgd2lucywgZmFsbGluZ1xuICAgKiBiYWNrIHRvIHRoZSBjbGFzcydzIHNtYWxsIHN0YXRpYyBsaXN0LlxuICAgKi9cbiAgbW9kZWxDbGFzcz86IE1vZGVsQ2xhc3M7XG4gIC8qKlxuICAgKiBPcGVyYXRvci1zdXBwbGllZCBmYWxsYmFjayBpZHMgdHJpZWQgKmZpcnN0KiBpbiB0aGUgbm8tZXhwbGljaXQsIG5vLWNsYXNzXG4gICAqIHBhdGggKGUuZy4gYSByZWd1bGF0ZWQgd29ya3NwYWNlIHBpbm5lZCB0byBhbiBhcHByb3ZlZCBzdWJzZXQpLCBhaGVhZCBvZlxuICAgKiB0aGUgYXV0by1jbGFzc2lmaWVkIGNhdGFsb2d1ZS5cbiAgICovXG4gIGZhbGxiYWNrcz86IHJlYWRvbmx5IHN0cmluZ1tdO1xufVxuXG4vKiogT3V0Y29tZSBvZiB7QGxpbmsgcmVzb2x2ZU1vZGVsfTogdGhlIGNob3NlbiBpZCBwbHVzIGhvdyBpdCB3YXMgcmVhY2hlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRNb2RlbFNlbGVjdGlvbiB7XG4gIG1vZGVsSWQ6IHN0cmluZztcbiAgc291cmNlOiBcImV4cGxpY2l0XCIgfCBcImZ1enp5LW1hdGNoXCIgfCBcImNsYXNzXCIgfCBcImZhbGxiYWNrXCI7XG59XG5cbi8qKiBJbnRlbnQgKyBjYXRhbG9ndWUga25vYnMgcGFzc2VkIHRvIHtAbGluayBzZWxlY3RNb2RlbH0uICovXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdE1vZGVsSW5wdXQgZXh0ZW5kcyBSZXNvbHZlTW9kZWxJbnB1dCB7XG4gIC8qKiBUVEwgb3ZlcnJpZGUgZm9yIHRoZSBjYWNoZWQgYC9zZXJ2aW5nLWVuZHBvaW50c2AgbGlzdGluZywgaW4gbXMuICovXG4gIHR0bE1zPzogbnVtYmVyO1xufVxuXG4vKiogVFRMIG92ZXJyaWRlIG1lcmdlZCBpbnRvIGEge0BsaW5rIE1vZGVsUXVlcnl9IGZvciB7QGxpbmsgc2VhcmNoTW9kZWxzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoTW9kZWxzSW5wdXQgZXh0ZW5kcyBNb2RlbFF1ZXJ5IHtcbiAgLyoqIFRUTCBvdmVycmlkZSBmb3IgdGhlIGNhY2hlZCBgL3NlcnZpbmctZW5kcG9pbnRzYCBsaXN0aW5nLCBpbiBtcy4gKi9cbiAgdHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogUm91bmQgYSBGdXNlIHNjb3JlIHRvIHRoZSBkaXNwbGF5IHByZWNpc2lvbiBzbyB2ZXJzaW9uIHNpYmxpbmdzIHRoYXQgbWF0Y2ggYVxuICogdG9rZW4gaWRlbnRpY2FsbHkgKGUuZy4gYG9wdXMtNC03YCB2cyBgb3B1cy00LThgIGZvciB0aGUgcXVlcnkgYFwib3B1c1wiYCkgdGllXG4gKiBvbiBtYXRjaCBhbmQgbGV0IHRoZSBjbGFzcyAvIHdpdGhpbi1jbGFzcyByYW5rIGRlY2lkZSAtIHdoaWNoIGlzIHdoYXRcbiAqIHN1cmZhY2VzIHRoZSBuZXdlciwgaGlnaGVyLXF1YWxpdHkgc2libGluZy5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hCdWNrZXQoc2NvcmU6IG51bWJlciB8IHVuZGVmaW5lZCk6IG51bWJlciB7XG4gIHJldHVybiBNYXRoLnJvdW5kKChzY29yZSA/PyAwKSAqIDEwMDApO1xufVxuXG5mdW5jdGlvbiBtb2RlbFZhcmlhbnRSYW5rKG5hbWU6IHN0cmluZyk6IG51bWJlciB7XG4gIGlmICghLyg/Ol58Wy1fLl0pZ3B0KD86Wy1fLl18JCkvaS50ZXN0KG5hbWUpKSByZXR1cm4gMjtcbiAgaWYgKC8oPzpefFstXy5dKXNvbCg/OlstXy5dfCQpL2kudGVzdChuYW1lKSkgcmV0dXJuIDA7XG4gIGlmICgvKD86XnxbLV8uXSlsdW5hKD86Wy1fLl18JCkvaS50ZXN0KG5hbWUpKSByZXR1cm4gMTtcbiAgcmV0dXJuIDI7XG59XG5cbi8qKlxuICogUmFuayB0aGUgbGl2ZSBjYXRhbG9ndWUgYWdhaW5zdCBhIHtAbGluayBNb2RlbFF1ZXJ5fSwgYmVzdC1maXJzdC5cbiAqXG4gKiBDYW5kaWRhdGVzIGFyZSB0aGUgY2xhc3NpZmllZCBlbmRwb2ludHMgaW4gdGhlIGVsaWdpYmxlIGNsYXNzZXM6XG4gKiB7QGxpbmsgY2xhc3Nlc0F0T3JCZWxvd30gdGhlIHJlcXVlc3RlZCBgbW9kZWxDbGFzc2AsIG9yIC0gd2hlbiBub25lIGlzIGdpdmVuXG4gKiAtIHRoZSBjaGF0IGJhbmRzIG9ubHkgKHtAbGluayBDSEFUX0NMQVNTX09SREVSfSksIHNvIGEgZ2VuZXJhbCBhc2sgbmV2ZXJcbiAqIHN1cmZhY2VzIGFuIGVtYmVkZGluZyBlbmRwb2ludC4gRWFjaCBjbGFzcyBidWNrZXQgaXMgYWxyZWFkeSBiZXN0LWZpcnN0IGZyb21cbiAqIHtAbGluayBjbGFzc2lmeS5jbGFzc2lmeUVuZHBvaW50c30uIFJhbmtpbmcgaXMgKiptYXRjaCB0aGVuIGNsYXNzKio6XG4gKlxuICogMS4gV2l0aCBhIGBzZWFyY2hgLCBvbmx5IGVuZHBvaW50cyBtYXRjaGluZyBpdCBzdXJ2aXZlLCBvcmRlcmVkIGJ5IG1hdGNoXG4gKiAgICBkaXN0YW5jZSAoYnVja2V0ZWQgdmlhIHtAbGluayBtYXRjaEJ1Y2tldH0gc28gbmVhci1pZGVudGljYWwgc2NvcmVzIHRpZSksXG4gKiAgICB0aGVuIGJ5IHZlcnNpb24sIHByZWZlcnJlZCBtb2RlbCB2YXJpYW50LCBjbGFzcyAobW9yZSBjYXBhYmxlIGZpcnN0KSwgYW5kXG4gKiAgICB0aGUgc3RhYmxlIHdpdGhpbi1jbGFzcyByYW5rLlxuICogMi4gV2l0aG91dCBhIGBzZWFyY2hgLCB0aGUgY2xhc3MtdGhlbi1yYW5rIGNhbmRpZGF0ZSBvcmRlciBzdGFuZHMuXG4gKlxuICogQSBgbGltaXRgIHRydW5jYXRlcyB0aGUgcmVzdWx0LiBSZXR1cm5zIGBbXWAgd2hlbiBub3RoaW5nIGlzIGVsaWdpYmxlIG9yXG4gKiBtYXRjaGVzIC0gY2FsbGVycyBsYXllciB0aGVpciBvd24gZmFsbGJhY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsb29rdXBNb2RlbHMoXG4gIGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuICBxdWVyeTogTW9kZWxRdWVyeSA9IHt9LFxuKTogUmFua2VkTW9kZWxbXSB7XG4gIGNvbnN0IGNsYXNzaWZpZWQgPSBjbGFzc2lmeS5jbGFzc2lmeUVuZHBvaW50cyhlbmRwb2ludHMpO1xuICBjb25zdCBlbGlnaWJsZSA9XG4gICAgcXVlcnkubW9kZWxDbGFzcyAhPT0gdW5kZWZpbmVkID8gY2xhc3Nlc0F0T3JCZWxvdyhxdWVyeS5tb2RlbENsYXNzKSA6IENIQVRfQ0xBU1NfT1JERVI7XG5cbiAgLy8gRmxhdHRlbiBlbGlnaWJsZSBjbGFzc2VzIGluIGNhcGFiaWxpdHkgb3JkZXIsIGNhcnJ5aW5nIGVhY2ggZW5kcG9pbnQnc1xuICAvLyBjbGFzczsgYnVja2V0IG9yZGVyIGlzIGFscmVhZHkgYmVzdC1maXJzdC5cbiAgY29uc3QgY2FuZGlkYXRlczogUmFua2VkTW9kZWxbXSA9IFtdO1xuICBmb3IgKGNvbnN0IG1vZGVsQ2xhc3Mgb2YgZWxpZ2libGUpIHtcbiAgICBmb3IgKGNvbnN0IGVuZHBvaW50IG9mIGNsYXNzaWZpZWRbbW9kZWxDbGFzc10pIHtcbiAgICAgIGlmIChxdWVyeS5yZXF1aXJlc1Rvb2xzICYmICFjbGFzc2lmeS5lbmRwb2ludENhcGFiaWxpdGllcyhlbmRwb2ludCkudG9vbHMpIGNvbnRpbnVlO1xuICAgICAgY2FuZGlkYXRlcy5wdXNoKHsgZW5kcG9pbnQsIG1vZGVsQ2xhc3MgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2VhcmNoID0gcXVlcnkuc2VhcmNoPy50cmltKCk7XG4gIGxldCByYW5rZWQ6IFJhbmtlZE1vZGVsW107XG4gIGlmIChzZWFyY2gpIHtcbiAgICBjb25zdCBncHRGYW1pbHlTZWFyY2ggPSBzZWFyY2gudG9Mb3dlckNhc2UoKSA9PT0gXCJncHRcIjtcbiAgICBjb25zdCB2ZXJzaW9uZWRGYW1pbHlTZWFyY2ggPSBWRVJTSU9ORURfRkFNSUxZX1NFQVJDSEVTLmhhcyhzZWFyY2gudG9Mb3dlckNhc2UoKSk7XG4gICAgY29uc3Qgc2NvcmVzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgICBmb3IgKGNvbnN0IG1hdGNoIG9mIHNlYXJjaFNlcnZpbmdFbmRwb2ludHMoXG4gICAgICBzZWFyY2gsXG4gICAgICBjYW5kaWRhdGVzLm1hcCgoYykgPT4gYy5lbmRwb2ludCksXG4gICAgICBxdWVyeS50aHJlc2hvbGQgIT09IHVuZGVmaW5lZCA/IHsgdGhyZXNob2xkOiBxdWVyeS50aHJlc2hvbGQgfSA6IHt9LFxuICAgICkpIHtcbiAgICAgIHNjb3Jlcy5zZXQobWF0Y2guZW5kcG9pbnQubmFtZSwgbWF0Y2guc2NvcmUpO1xuICAgIH1cbiAgICAvLyBgQXJyYXkucHJvdG90eXBlLnNvcnRgIGlzIHN0YWJsZSwgc28gZW5kcG9pbnRzIGVxdWFsIG9uIG1hdGNoIGFuZCBjbGFzc1xuICAgIC8vIGtlZXAgdGhlaXIgYmVzdC1maXJzdCB3aXRoaW4tY2xhc3Mgb3JkZXIuXG4gICAgcmFua2VkID0gY2FuZGlkYXRlc1xuICAgICAgLmZpbHRlcigoYykgPT4gc2NvcmVzLmhhcyhjLmVuZHBvaW50Lm5hbWUpKVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGMpID0+ICFncHRGYW1pbHlTZWFyY2ggfHwgIS8oPzpefFstXy5dKWdwdFstXy5dP29zcyg/OlstXy5dfCQpL2kudGVzdChjLmVuZHBvaW50Lm5hbWUpLFxuICAgICAgKVxuICAgICAgLm1hcCgoYykgPT4gKHsgLi4uYywgc2NvcmU6IHNjb3Jlcy5nZXQoYy5lbmRwb2ludC5uYW1lKSB9KSlcbiAgICAgIC5zb3J0KChhLCBiKSA9PiB7XG4gICAgICAgIGNvbnN0IGJ5TWF0Y2ggPSBtYXRjaEJ1Y2tldChhLnNjb3JlKSAtIG1hdGNoQnVja2V0KGIuc2NvcmUpO1xuICAgICAgICBpZiAoYnlNYXRjaCAhPT0gMCkgcmV0dXJuIGJ5TWF0Y2g7XG4gICAgICAgIGlmICh2ZXJzaW9uZWRGYW1pbHlTZWFyY2gpIHtcbiAgICAgICAgICBjb25zdCBhVmVyc2lvbiA9IGNsYXNzaWZ5LnZlcnNpb25UdXBsZShhLmVuZHBvaW50Lm5hbWUpO1xuICAgICAgICAgIGNvbnN0IGJWZXJzaW9uID0gY2xhc3NpZnkudmVyc2lvblR1cGxlKGIuZW5kcG9pbnQubmFtZSk7XG4gICAgICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IDM7IGluZGV4KyspIHtcbiAgICAgICAgICAgIGNvbnN0IGJ5VmVyc2lvbiA9IChiVmVyc2lvbltpbmRleF0gPz8gMCkgLSAoYVZlcnNpb25baW5kZXhdID8/IDApO1xuICAgICAgICAgICAgaWYgKGJ5VmVyc2lvbiAhPT0gMCkgcmV0dXJuIGJ5VmVyc2lvbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYnlWYXJpYW50ID0gbW9kZWxWYXJpYW50UmFuayhhLmVuZHBvaW50Lm5hbWUpIC0gbW9kZWxWYXJpYW50UmFuayhiLmVuZHBvaW50Lm5hbWUpO1xuICAgICAgICBpZiAoYnlWYXJpYW50ICE9PSAwKSByZXR1cm4gYnlWYXJpYW50O1xuICAgICAgICByZXR1cm4gTU9ERUxfQ0xBU1NfT1JERVIuaW5kZXhPZihhLm1vZGVsQ2xhc3MpIC0gTU9ERUxfQ0xBU1NfT1JERVIuaW5kZXhPZihiLm1vZGVsQ2xhc3MpO1xuICAgICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcmFua2VkID0gY2FuZGlkYXRlcztcbiAgfVxuXG4gIHJldHVybiBxdWVyeS5saW1pdCAhPT0gdW5kZWZpbmVkID8gcmFua2VkLnNsaWNlKDAsIE1hdGgubWF4KDAsIHF1ZXJ5LmxpbWl0KSkgOiByYW5rZWQ7XG59XG5cbi8qKlxuICogQ29sbGFwc2Uge0BsaW5rIGxvb2t1cE1vZGVsc30gdG8gYSBzaW5nbGUgaWQ6IHRoZSBjbG9zZXN0IGVuZHBvaW50IHRvIGBzZWFyY2hgXG4gKiBpbiBhIGNhdGFsb2d1ZSBzbmFwc2hvdCwgb3IgdGhlIGlucHV0IHZlcmJhdGltIHdoZW4gbm90aGluZyBzY29yZXMgd2l0aGluIHRoZVxuICogdGhyZXNob2xkLlxuICpcbiAqIFRoZSByYW5rLWJhc2VkIGNvdW50ZXJwYXJ0IHRvIHRoZSBGdXNlLW9ubHkge0BsaW5rIHJlc29sdmVNb2RlbElkfTogZXF1YWxcbiAqIG1hdGNoIHNjb3JlcyBhcmUgYnJva2VuIGJ5IGNsYXNzIGFuZCB0aGVuIHdpdGhpbi1jbGFzcyB2ZXJzaW9uLCBzbyBhIGxvb3NlXG4gKiBgXCJvcHVzXCJgIHByZWZlcnMgYG9wdXMtNWAgb3ZlciBgb3B1cy00LTdgIGluc3RlYWQgb2YgcGlja2luZyB3aGljaGV2ZXJcbiAqIHNpYmxpbmcgRnVzZSBoYXBwZW5lZCB0byBvcmRlciBmaXJzdC4gUmV0dXJuaW5nIHRoZSBpbnB1dCB1bm1hdGNoZWQgKHJhdGhlclxuICogdGhhbiBhIG5lYXIgbmVpZ2hib3VyKSBpcyBkZWxpYmVyYXRlIC0gYSBkZWxpYmVyYXRlIGVuZHBvaW50IGlkIGlzIG5ldmVyXG4gKiBzaWxlbnRseSByZXdyaXR0ZW4sIGFuZCBEYXRhYnJpY2tzIHN1cmZhY2VzIGEgY2xlYW4gNDA0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmFua01vZGVsSWQoXG4gIGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuICBzZWFyY2g6IHN0cmluZyxcbiAgb3B0aW9uczogUmVzb2x2ZU1vZGVsT3B0aW9ucyA9IHt9LFxuKTogUmVzb2x2ZWRNb2RlbCB7XG4gIGNvbnN0IFt0b3BdID0gbG9va3VwTW9kZWxzKGVuZHBvaW50cywge1xuICAgIHNlYXJjaCxcbiAgICBsaW1pdDogMSxcbiAgICAuLi4ob3B0aW9ucy50aHJlc2hvbGQgIT09IHVuZGVmaW5lZCA/IHsgdGhyZXNob2xkOiBvcHRpb25zLnRocmVzaG9sZCB9IDoge30pLFxuICAgIC4uLihvcHRpb25zLnJlcXVpcmVzVG9vbHMgIT09IHVuZGVmaW5lZCA/IHsgcmVxdWlyZXNUb29sczogb3B0aW9ucy5yZXF1aXJlc1Rvb2xzIH0gOiB7fSksXG4gIH0pO1xuICBpZiAoIXRvcCkgcmV0dXJuIHsgbW9kZWxJZDogc2VhcmNoLCBtYXRjaGVkOiBmYWxzZSB9O1xuICByZXR1cm4geyBtb2RlbElkOiB0b3AuZW5kcG9pbnQubmFtZSwgbWF0Y2hlZDogdHJ1ZSwgc2NvcmU6IHRvcC5zY29yZSB9O1xufVxuXG4vKipcbiAqIHtAbGluayByYW5rTW9kZWxJZH0gYWdhaW5zdCBhIGNhdGFsb2d1ZSB0aGUgY2FsbGVyIG1heSBiZSBob2xkaW5nIHN0YWxlOlxuICogbWF0Y2ggdGhlIGxvYWRlZCBzbmFwc2hvdCwgYW5kIG9uIGEgbWlzcyByZWxvYWQgb25jZSB3aXRoIGBmb3JjZWAgYW5kIG1hdGNoXG4gKiBhZ2Fpbi4gVGhhdCB3YXkgYSBtb2RlbCBkZXBsb3llZCBhZnRlciB0aGUgY2F0YWxvZ3VlIHdhcyBjYWNoZWQgc3RpbGxcbiAqIHJlc29sdmVzIG9uIGZpcnN0IHVzZSwgd2l0aG91dCBhIHJlc3RhcnQgYW5kIHdpdGhvdXQgZ2l2aW5nIHVwIGNhY2hpbmcuXG4gKlxuICogVGhlIGNhdGFsb2d1ZSBhcnJpdmVzIGFzIGEgbG9hZGVyIHJhdGhlciB0aGFuIGEgY2xpZW50IHNvIHRoZSBjYWxsZXIga2VlcHNcbiAqIG93bmVyc2hpcCBvZiAqaG93KiBpdCBpcyBjYWNoZWQgLSB7QGxpbmsgbGlzdFNlcnZpbmdFbmRwb2ludHN9IGFuZCBpdHNcbiAqIGBDYWNoZU1hbmFnZXJgLCBhIHBsYWluIHByb2Nlc3MtbGlmZXRpbWUgZmllbGQgaW4gYSBDTEksIG9yIGEgdGVzdCBkb3VibGUuXG4gKiBPbmx5IG9uZSByZWxvYWQgaXMgYXR0ZW1wdGVkOiBhIGdlbnVpbmVseSB1bmtub3duIG5hbWUgc2hvdWxkIGZhaWwgZmFzdFxuICogcmF0aGVyIHRoYW4gcmUtbGlzdCBvbiBldmVyeSByZXF1ZXN0LlxuICpcbiAqIEBwYXJhbSBsb2FkIC0gUmV0dXJucyB0aGUgY2F0YWxvZ3VlOyBgZm9yY2VgIGFza3MgaXQgdG8gYnlwYXNzIGl0cyBjYWNoZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJhbmtNb2RlbElkTGl2ZShcbiAgbG9hZDogKGZvcmNlOiBib29sZWFuKSA9PiBQcm9taXNlPHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXT4sXG4gIHNlYXJjaDogc3RyaW5nLFxuICBvcHRpb25zOiBSZXNvbHZlTW9kZWxPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFJlc29sdmVkTW9kZWw+IHtcbiAgY29uc3QgcmVzb2x2ZWQgPSByYW5rTW9kZWxJZChhd2FpdCBsb2FkKGZhbHNlKSwgc2VhcmNoLCBvcHRpb25zKTtcbiAgaWYgKHJlc29sdmVkLm1hdGNoZWQpIHJldHVybiByZXNvbHZlZDtcbiAgcmV0dXJuIHJhbmtNb2RlbElkKGF3YWl0IGxvYWQodHJ1ZSksIHNlYXJjaCwgb3B0aW9ucyk7XG59XG5cbi8qKlxuICogUmFuayBhIHdvcmtzcGFjZSdzIGNhdGFsb2d1ZSBpbiBvbmUgY2FsbDogbGlzdCBpdHMgYC9zZXJ2aW5nLWVuZHBvaW50c2BcbiAqIChjYWNoZWQpIGFuZCBydW4ge0BsaW5rIGxvb2t1cE1vZGVsc30gb3ZlciB0aGUgcmVzdWx0LiBUaGUgbGlzdCBjb3VudGVycGFydCB0b1xuICoge0BsaW5rIHNlbGVjdE1vZGVsfSwgZm9yIGEgY29uc3VtZXIgdGhhdCB3YW50cyB0aGUgZnVsbCByYW5rZWQgc2V0IChhIG1vZGVsXG4gKiBwaWNrZXIsIGEgQ0xJKSByYXRoZXIgdGhhbiBhIHNpbmdsZSBpZC4gQ2F0YWxvZ3VlIGZldGNoZXMgZmFpbCBsb3VkOiBuZXR3b3JrXG4gKiAvIGF1dGggZXJyb3JzIHByb3BhZ2F0ZSBzbyB0aGUgY2FsbGVyIHNlZXMgdGhlIHJlYWwgU0RLIG1lc3NhZ2UuXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCB1c2VkIGFzIHRoZSBjYWNoZSBrZXkuIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkXG4gKiAgIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlYXJjaE1vZGVscyhcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBob3N0OiBzdHJpbmcsXG4gIGlucHV0OiBTZWFyY2hNb2RlbHNJbnB1dCA9IHt9LFxuKTogUHJvbWlzZTxSYW5rZWRNb2RlbFtdPiB7XG4gIGNvbnN0IGVuZHBvaW50cyA9IGF3YWl0IGxpc3RTZXJ2aW5nRW5kcG9pbnRzKFxuICAgIGNsaWVudCxcbiAgICBob3N0LFxuICAgIGlucHV0LnR0bE1zICE9PSB1bmRlZmluZWQgPyB7IHR0bE1zOiBpbnB1dC50dGxNcyB9IDoge30sXG4gICk7XG4gIHJldHVybiBsb29rdXBNb2RlbHMoZW5kcG9pbnRzLCBpbnB1dCk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIG1vZGVsIGlkIGZvciBhIHdvcmtzcGFjZSBpbiBvbmUgY2FsbDogbGlzdCBpdHMgYC9zZXJ2aW5nLWVuZHBvaW50c2BcbiAqIChjYWNoZWQpIGFuZCBydW4ge0BsaW5rIHJlc29sdmVNb2RlbH0gb3ZlciB0aGUgcmVzdWx0LiBUaGlzIGlzIHRoZSBlbnRyeVxuICogcG9pbnQgZm9yIGFueSBjb25zdW1lciB0aGF0IGhvbGRzIGEgYFdvcmtzcGFjZUNsaWVudGAgYW5kIGp1c3Qgd2FudHMgYSB1c2FibGVcbiAqIG1vZGVsIG5hbWUgLSBhIExha2VmbG93IGpvYiwgYSBvbmUtb2ZmIHNjcmlwdCwgb3IgdGhlIE1hc3RyYSBwbHVnaW4gYWxpa2UuXG4gKlxuICogQ2hlYXAgZXhpdDogd2hlbiBhbiBgZXhwbGljaXRgIG5hbWUgaXMgZ2l2ZW4sIGBmdXp6eWAgaXMgb2ZmLCBhbmQgdG9vbFxuICogY2FwYWJpbGl0eSBpcyBub3QgcmVxdWlyZWQsIHRoZSBjYXRhbG9ndWUgaXMgbmV2ZXIgZmV0Y2hlZC4gQ2F0YWxvZ3VlXG4gKiBmZXRjaGVzIG90aGVyd2lzZSBmYWlsIGxvdWQ6IG5ldHdvcmsgLyBhdXRoIGVycm9ycyBwcm9wYWdhdGUgc28gdGhlIGNhbGxlclxuICogc2VlcyB0aGUgcmVhbCBTREsgbWVzc2FnZSBpbnN0ZWFkIG9mIGEgc2lsZW50IGZhbGxiYWNrLlxuICpcbiAqIEBwYXJhbSBob3N0IC0gV29ya3NwYWNlIGhvc3QgdXNlZCBhcyB0aGUgY2FjaGUga2V5LiBQYXNzIHRoZSB2YWx1ZSByZXNvbHZlZFxuICogICBmcm9tIGBjbGllbnQuY29uZmlnLmdldEhvc3QoKWAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZWxlY3RNb2RlbChcbiAgY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlLFxuICBob3N0OiBzdHJpbmcsXG4gIGlucHV0OiBTZWxlY3RNb2RlbElucHV0ID0ge30sXG4pOiBQcm9taXNlPFJlc29sdmVkTW9kZWxTZWxlY3Rpb24+IHtcbiAgaWYgKGlucHV0LmV4cGxpY2l0ICE9PSB1bmRlZmluZWQgJiYgaW5wdXQuZnV6enkgPT09IGZhbHNlICYmICFpbnB1dC5yZXF1aXJlc1Rvb2xzKSB7XG4gICAgcmV0dXJuIHsgbW9kZWxJZDogaW5wdXQuZXhwbGljaXQsIHNvdXJjZTogXCJleHBsaWNpdFwiIH07XG4gIH1cbiAgY29uc3QgZW5kcG9pbnRzID0gYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHMoY2xpZW50LCBob3N0LCB7XG4gICAgLi4uKGlucHV0LnR0bE1zICE9PSB1bmRlZmluZWQgPyB7IHR0bE1zOiBpbnB1dC50dGxNcyB9IDoge30pLFxuICB9KTtcbiAgcmV0dXJuIHJlc29sdmVNb2RlbChlbmRwb2ludHMsIGlucHV0KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgc2luZ2xlIG1vZGVsIGlkIGZyb20gdGhlIGxpdmUgY2F0YWxvZ3VlIGFuZCBjYWxsZXIgaW50ZW50LFxuICogZGVsZWdhdGluZyB0aGUgbGl2ZSBzZWxlY3Rpb24gdG8ge0BsaW5rIGxvb2t1cE1vZGVsc30gd2l0aCBgbGltaXQ6IDFgLlxuICpcbiAqIDEuICoqRXhwbGljaXQgYXNrKio6IHdpdGggYGZ1enp5YCBvZmYsIHJldHVybmVkIHZlcmJhdGltOyBvdGhlcndpc2VcbiAqICAgIGZ1enp5LXJhbmtlZCB3aXRoaW4gdGhlIChvcHRpb25hbCkgY2xhc3MgY2VpbGluZyBhbmQgdGhlIGJlc3QgdGFrZW4sXG4gKiAgICBmYWxsaW5nIGJhY2sgdG8gdGhlIGlucHV0IHZlcmJhdGltIHdoZW4gbm90aGluZyBtYXRjaGVzLlxuICogMi4gKipObyBleHBsaWNpdCBhc2sqKjogYW4gb3BlcmF0b3ItcGlubmVkIGBmYWxsYmFja2AgdGhhdCBleGlzdHMgaW4gdGhlIGxpdmVcbiAqICAgIGNhdGFsb2d1ZSB3aW5zIGZpcnN0OyB0aGVuIHRoZSByYW5rZWQgbGl2ZSBjYXRhbG9ndWUgKGNsYXNzIGNlaWxpbmdcbiAqICAgIGFwcGxpZWQpOyB0aGVuIHRoZSBzdGF0aWMge0BsaW5rIEZBTExCQUNLX01PREVMX0lEU30gZmxvb3Igd2hlbiB0aGVcbiAqICAgIGNhdGFsb2d1ZSB5aWVsZHMgbm90aGluZyBpbiByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVNb2RlbChcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIGlucHV0OiBSZXNvbHZlTW9kZWxJbnB1dCA9IHt9LFxuKTogUmVzb2x2ZWRNb2RlbFNlbGVjdGlvbiB7XG4gIGlmIChpbnB1dC5leHBsaWNpdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKGlucHV0LmZ1enp5ID09PSBmYWxzZSkge1xuICAgICAgaWYgKGlucHV0LnJlcXVpcmVzVG9vbHMpIGFzc2VydFRvb2xTdXBwb3J0KGVuZHBvaW50cywgaW5wdXQuZXhwbGljaXQpO1xuICAgICAgcmV0dXJuIHsgbW9kZWxJZDogaW5wdXQuZXhwbGljaXQsIHNvdXJjZTogXCJleHBsaWNpdFwiIH07XG4gICAgfVxuICAgIGNvbnN0IFt0b3BdID0gbG9va3VwTW9kZWxzKGVuZHBvaW50cywgYnVpbGRRdWVyeShpbnB1dCwgaW5wdXQuZXhwbGljaXQpKTtcbiAgICBpZiAoaW5wdXQucmVxdWlyZXNUb29scyAmJiAhdG9wKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHRvb2wtY2FwYWJsZSBtb2RlbCBtYXRjaGVzIFwiJHtpbnB1dC5leHBsaWNpdH1cImApO1xuICAgIH1cbiAgICByZXR1cm4geyBtb2RlbElkOiB0b3A/LmVuZHBvaW50Lm5hbWUgPz8gaW5wdXQuZXhwbGljaXQsIHNvdXJjZTogXCJmdXp6eS1tYXRjaFwiIH07XG4gIH1cblxuICAvLyBPcGVyYXRvci1waW5uZWQgZmFsbGJhY2tzIHdpbiB3aGVuIHByZXNlbnQgYW5kIGxpdmUgKGUuZy4gYSByZWd1bGF0ZWRcbiAgLy8gd29ya3NwYWNlIHJlc3RyaWN0ZWQgdG8gYW4gYXBwcm92ZWQgc3Vic2V0KS5cbiAgaWYgKGlucHV0Lm1vZGVsQ2xhc3MgPT09IHVuZGVmaW5lZCAmJiBpbnB1dC5mYWxsYmFja3MgJiYgaW5wdXQuZmFsbGJhY2tzLmxlbmd0aCA+IDApIHtcbiAgICBjb25zdCBwcmVzZW50ID0gbmV3IFNldChcbiAgICAgIGVuZHBvaW50c1xuICAgICAgICAuZmlsdGVyKChlbmRwb2ludCkgPT4gIWlucHV0LnJlcXVpcmVzVG9vbHMgfHwgY2xhc3NpZnkuZW5kcG9pbnRDYXBhYmlsaXRpZXMoZW5kcG9pbnQpLnRvb2xzKVxuICAgICAgICAubWFwKChlbmRwb2ludCkgPT4gZW5kcG9pbnQubmFtZSksXG4gICAgKTtcbiAgICBjb25zdCBwaW5uZWQgPSBpbnB1dC5mYWxsYmFja3MuZmluZCgoaWQpID0+IHByZXNlbnQuaGFzKGlkKSk7XG4gICAgaWYgKHBpbm5lZCkgcmV0dXJuIHsgbW9kZWxJZDogcGlubmVkLCBzb3VyY2U6IFwiZmFsbGJhY2tcIiB9O1xuICB9XG5cbiAgY29uc3Qgc291cmNlID0gaW5wdXQubW9kZWxDbGFzcyAhPT0gdW5kZWZpbmVkID8gXCJjbGFzc1wiIDogXCJmYWxsYmFja1wiO1xuICBjb25zdCBbdG9wXSA9IGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGJ1aWxkUXVlcnkoaW5wdXQsIHVuZGVmaW5lZCkpO1xuICBpZiAodG9wKSByZXR1cm4geyBtb2RlbElkOiB0b3AuZW5kcG9pbnQubmFtZSwgc291cmNlIH07XG5cbiAgLy8gTGl2ZSBjYXRhbG9ndWUgeWllbGRlZCBub3RoaW5nIGluIHJhbmdlOiB3YWxrIHRoZSBzdGF0aWMgZmxvb3IuXG4gIGNvbnN0IGZsb29yU291cmNlID1cbiAgICBpbnB1dC5tb2RlbENsYXNzICE9PSB1bmRlZmluZWQgPyBtb2RlbHNGb3JDbGFzcyhpbnB1dC5tb2RlbENsYXNzKSA6IChpbnB1dC5mYWxsYmFja3MgPz8gW10pO1xuICBjb25zdCBmbG9vciA9IG9iamVjdC5zZXF1ZW5jZShmbG9vclNvdXJjZSkuY29uY2F0KEZBTExCQUNLX01PREVMX0lEUykuZGlzdGluY3QoKS50b0FycmF5KCk7XG4gIGlmIChpbnB1dC5yZXF1aXJlc1Rvb2xzKSB7XG4gICAgY29uc3QgYXZhaWxhYmxlID0gbmV3IFNldChcbiAgICAgIGVuZHBvaW50c1xuICAgICAgICAuZmlsdGVyKChlbmRwb2ludCkgPT4gY2xhc3NpZnkuZW5kcG9pbnRDYXBhYmlsaXRpZXMoZW5kcG9pbnQpLnRvb2xzKVxuICAgICAgICAubWFwKChlbmRwb2ludCkgPT4gZW5kcG9pbnQubmFtZSksXG4gICAgKTtcbiAgICBjb25zdCBzZWxlY3RlZCA9IGZsb29yLmZpbmQoKGlkKSA9PiBhdmFpbGFibGUuaGFzKGlkKSk7XG4gICAgaWYgKCFzZWxlY3RlZCkgdGhyb3cgbmV3IEVycm9yKFwiTm8gdG9vbC1jYXBhYmxlIG1vZGVsIGlzIGF2YWlsYWJsZVwiKTtcbiAgICByZXR1cm4geyBtb2RlbElkOiBzZWxlY3RlZCwgc291cmNlIH07XG4gIH1cbiAgcmV0dXJuIHsgbW9kZWxJZDogcGlja0ZpcnN0QXZhaWxhYmxlKGZsb29yLCBlbmRwb2ludHMpLCBzb3VyY2UgfTtcbn1cblxuLyoqIEJ1aWxkIGEge0BsaW5rIE1vZGVsUXVlcnl9IGZyb20ge0BsaW5rIFJlc29sdmVNb2RlbElucHV0fSBmb3IgdGhlIGBsaW1pdDogMWAgZGVsZWdhdGlvbi4gKi9cbmZ1bmN0aW9uIGJ1aWxkUXVlcnkoaW5wdXQ6IFJlc29sdmVNb2RlbElucHV0LCBzZWFyY2g6IHN0cmluZyB8IHVuZGVmaW5lZCk6IE1vZGVsUXVlcnkge1xuICByZXR1cm4ge1xuICAgIC4uLihzZWFyY2ggIT09IHVuZGVmaW5lZCA/IHsgc2VhcmNoIH0gOiB7fSksXG4gICAgLi4uKGlucHV0Lm1vZGVsQ2xhc3MgIT09IHVuZGVmaW5lZCA/IHsgbW9kZWxDbGFzczogaW5wdXQubW9kZWxDbGFzcyB9IDoge30pLFxuICAgIC4uLihpbnB1dC5yZXF1aXJlc1Rvb2xzICE9PSB1bmRlZmluZWQgPyB7IHJlcXVpcmVzVG9vbHM6IGlucHV0LnJlcXVpcmVzVG9vbHMgfSA6IHt9KSxcbiAgICAuLi4oaW5wdXQudGhyZXNob2xkICE9PSB1bmRlZmluZWQgPyB7IHRocmVzaG9sZDogaW5wdXQudGhyZXNob2xkIH0gOiB7fSksXG4gICAgbGltaXQ6IDEsXG4gIH07XG59XG5cbi8qKiBUaHJvdyB3aGVuIGFuIGV4cGxpY2l0IGlkIGlzIGFic2VudCBvciBub3QgdmVyaWZpZWQgZm9yIGZ1bmN0aW9uIHRvb2xzLiAqL1xuZnVuY3Rpb24gYXNzZXJ0VG9vbFN1cHBvcnQoZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sIG1vZGVsSWQ6IHN0cmluZyk6IHZvaWQge1xuICBjb25zdCBlbmRwb2ludCA9IGVuZHBvaW50cy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5uYW1lID09PSBtb2RlbElkKTtcbiAgaWYgKCFlbmRwb2ludCB8fCAhY2xhc3NpZnkuZW5kcG9pbnRDYXBhYmlsaXRpZXMoZW5kcG9pbnQpLnRvb2xzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBNb2RlbCBcIiR7bW9kZWxJZH1cIiBkb2VzIG5vdCBzdXBwb3J0IGZ1bmN0aW9uIHRvb2xzYCk7XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kIHRoZSBmaXJzdCBpZCBpbiBgY2FuZGlkYXRlc2Agd2hvc2UgZW5kcG9pbnQgaXMgcHJlc2VudCBpbiBgZW5kcG9pbnRzYC5cbiAqIFJldHVybnMgdGhlIHRvcCBjYW5kaWRhdGUgd2hlbiB0aGUgd29ya3NwYWNlIGhhcyBub25lIG9mIHRoZW0gc28gY2FsbGVyc1xuICogYWx3YXlzIGdldCBhIHN0cmluZzsgYW4gb2ZmbGluZSB3b3Jrc3BhY2UgdGhlbiByZWNlaXZlcyBhIGNsZWFuIDQwNCBmcm9tXG4gKiBEYXRhYnJpY2tzIGluc3RlYWQgb2YgYSBtYWxmb3JtZWQgY29uZmlnLlxuICovXG5mdW5jdGlvbiBwaWNrRmlyc3RBdmFpbGFibGUoXG4gIGNhbmRpZGF0ZXM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbik6IHN0cmluZyB7XG4gIGNvbnN0IHByZXNlbnQgPSBuZXcgU2V0KGVuZHBvaW50cy5tYXAoKGUpID0+IGUubmFtZSkpO1xuICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKHByZXNlbnQuaGFzKGNhbmRpZGF0ZSkpIHJldHVybiBjYW5kaWRhdGU7XG4gIH1cbiAgcmV0dXJuIGNhbmRpZGF0ZXNbMF0gPz8gRkFMTEJBQ0tfTU9ERUxfSURTWzBdITtcbn1cbiJdfQ==
|
|
271
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzb2x2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZXNvbHZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9CRztBQUVILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNoRCxPQUFPLEVBQ0wsVUFBVSxJQUFJLGlCQUFpQixFQUMvQixVQUFVLElBQUksa0JBQWtCLEdBR2pDLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUNMLFFBQVEsRUFDUixLQUFLLEdBSU4sTUFBTSx5QkFBeUIsQ0FBQztBQUVqQyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25FLE9BQU8sRUFDTCxvQkFBb0IsR0FLckIsTUFBTSxjQUFjLENBQUM7QUFJdEIsOEVBQThFO0FBQzlFLE1BQU0sMkJBQTJCLEdBQUcsS0FBSyxDQUFDO0FBRTFDLE1BQU0saUJBQWlCLEdBQW9EO0lBQ3pFLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxZQUFZO0lBQy9ELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxZQUFZLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxZQUFZO0lBQy9ELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxRQUFRO0lBQ3ZELENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxpQkFBaUIsQ0FBQyxTQUFTO0NBQzFELENBQUM7QUEyREY7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQzFCLFNBQTRDLEVBQzVDLFFBQW9CLEVBQUU7SUFFdEIsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsQ0FBQyxRQUFRLENB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LFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3RELEtBQUssTUFBTSxTQUFTLElBQUksVUFBVSxFQUFFLENBQUM7UUFDbkMsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQztZQUFFLE9BQU8sU0FBUyxDQUFDO0lBQy9DLENBQUM7SUFDRCxPQUFPLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDLENBQUUsQ0FBQztBQUNqRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBXb3Jrc3BhY2UtYXdhcmUgbW9kZWwgc2VsZWN0aW9uLlxuICpcbiAqIEdpdmVuIGEgY2FsbGVyJ3MgaW50ZW50IC0gYSBzZWFyY2ggc3RyaW5nLCBhIGNhcGFiaWxpdHkge0BsaW5rIE1vZGVsQ2xhc3N9XG4gKiBjZWlsaW5nLCBib3RoLCBvciBub3RoaW5nIC0gdGhlIHRvb2xraXQgcmV0dXJucyBtYXRjaGluZyBlbmRwb2ludHMgcmFua2VkIGJ5XG4gKiBtYXRjaCBxdWFsaXR5IHRoZW4gY2xhc3MsIG9yIGNvbGxhcHNlcyB0byB0aGUgc2luZ2xlIGJlc3QgaWQgdGhlIHdvcmtzcGFjZVxuICogYWN0dWFsbHkgaGFzLCBkZWdyYWRpbmcgZnJvbSBcImJlc3QgaW4gcmFuZ2VcIiBkb3duIHRvIHRoZSBzdGF0aWMgZmFsbGJhY2tcbiAqIGZsb29yLiBTZWxlY3Rpb24gaXMgY2hhdC1vbmx5OiBlbWJlZGRpbmcgZW5kcG9pbnRzIHN1cmZhY2Ugb25seSB3aGVuXG4gKiBgbW9kZWxDbGFzc2AgaXMgZXhwbGljaXRseSB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9LlxuICpcbiAqIFR3byBzaGFwZXMgb2Ygc2VsZWN0aW9uLCBlYWNoIGluIGEgcHVyZSBmb3JtIChvdmVyIGFuIGVuZHBvaW50IGxpc3QgdGhlXG4gKiBjYWxsZXIgYWxyZWFkeSBob2xkcykgYW5kIGFuIEkvTyB3cmFwcGVyICh0aGF0IGxpc3RzIGAvc2VydmluZy1lbmRwb2ludHNgXG4gKiBmaXJzdCk6IHJhbmtpbmcsIHdoaWNoIHJldHVybnMgYSBtYXRjaC0gdGhlbiBjbGFzcy1vcmRlcmVkIGxpc3QsIGFuZFxuICogc2luZ2xlLXNlbGVjdGlvbiwgd2hpY2ggY29sbGFwc2VzIHRvIG9uZSBpZCBwbHVzIGhvdyBpdCB3YXMgcmVhY2hlZCBhbmRcbiAqIGxheWVycyB0aGUgb3BlcmF0b3ItcGlubmVkIGZhbGxiYWNrIC8gc3RhdGljLWZsb29yIHNhZmV0eSBuZXQgb24gdG9wLiBBIGNoYXRcbiAqIGBtb2RlbENsYXNzYCBhY3RzIGFzIGEgY2VpbGluZzogdGhhdCBiYW5kIGFuZCB0aGUgbGVzcy1jYXBhYmxlIGNoYXQgYmFuZHNcbiAqIGJlbG93IGl0IGFyZSBlbGlnaWJsZSAoc2VlIHtAbGluayBjbGFzc2VzQXRPckJlbG93fSksIHNvIGEgYGNoYXQtYmFsYW5jZWRgXG4gKiBhc2sgY2FuIGZhbGwgdG8gYGNoYXQtZmFzdGAgYnV0IG5ldmVyIGVzY2FsYXRlIHRvIGBjaGF0LXRoaW5raW5nYC5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgb2JqZWN0IH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7XG4gIE1vZGVsQ2xhc3MgYXMgTW9kZWxSc01vZGVsQ2xhc3MsXG4gIHJhbmtNb2RlbHMgYXMgcmFua01vZGVsc1dpdGhSdXN0LFxuICB0eXBlIE1vZGVsUXVlcnkgYXMgTW9kZWxSc01vZGVsUXVlcnksXG4gIHR5cGUgU2VydmluZ0VuZHBvaW50U3VtbWFyeSBhcyBNb2RlbFJzU2VydmluZ0VuZHBvaW50U3VtbWFyeSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvbW9kZWwtcnNcIjtcbmltcG9ydCB7XG4gIGNsYXNzaWZ5LFxuICBtb2RlbCxcbiAgdHlwZSBNb2RlbFF1ZXJ5LFxuICB0eXBlIFJhbmtlZE1vZGVsLFxuICB0eXBlIFNlcnZpbmdFbmRwb2ludFN1bW1hcnksXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbFwiO1xuXG5pbXBvcnQgeyBGQUxMQkFDS19NT0RFTF9JRFMsIG1vZGVsc0ZvckNsYXNzIH0gZnJvbSBcIi4vZmFsbGJhY2sudHNcIjtcbmltcG9ydCB7XG4gIGxpc3RTZXJ2aW5nRW5kcG9pbnRzLFxuICBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzLFxuICB0eXBlIFJlc29sdmVkTW9kZWwsXG4gIHR5cGUgUmVzb2x2ZU1vZGVsT3B0aW9ucyxcbiAgdHlwZSBXb3Jrc3BhY2VDbGllbnRMaWtlLFxufSBmcm9tIFwiLi9zZXJ2aW5nLnRzXCI7XG5cbnR5cGUgTW9kZWxDbGFzcyA9IG1vZGVsLk1vZGVsQ2xhc3M7XG5cbi8qKiBQcmVmZXJyZWQgbGl2ZSBmYW1pbHkgZm9yIGFuIHVuY29uZmlndXJlZCBnZW5lcmFsLXB1cnBvc2UgY2hhdCBkZWZhdWx0LiAqL1xuY29uc3QgREVGQVVMVF9NT0RFTF9GQU1JTFlfU0VBUkNIID0gXCJncHRcIjtcblxuY29uc3QgTU9ERUxfQ0xBU1NfVE9fUlM6IFJlYWRvbmx5PFJlY29yZDxNb2RlbENsYXNzLCBNb2RlbFJzTW9kZWxDbGFzcz4+ID0ge1xuICBbbW9kZWwuTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmddOiBNb2RlbFJzTW9kZWxDbGFzcy5DaGF0VGhpbmtpbmcsXG4gIFttb2RlbC5Nb2RlbENsYXNzLkNoYXRCYWxhbmNlZF06IE1vZGVsUnNNb2RlbENsYXNzLkNoYXRCYWxhbmNlZCxcbiAgW21vZGVsLk1vZGVsQ2xhc3MuQ2hhdEZhc3RdOiBNb2RlbFJzTW9kZWxDbGFzcy5DaGF0RmFzdCxcbiAgW21vZGVsLk1vZGVsQ2xhc3MuRW1iZWRkaW5nXTogTW9kZWxSc01vZGVsQ2xhc3MuRW1iZWRkaW5nLFxufTtcblxuLyoqIENhbGxlciBpbnRlbnQgcGFzc2VkIHRvIHtAbGluayByZXNvbHZlTW9kZWx9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlTW9kZWxJbnB1dCB7XG4gIC8qKlxuICAgKiBFeHBsaWNpdCBtb2RlbCBpZCAvIGxvb3NlIG5hbWUgKHBlci1yZXF1ZXN0IG92ZXJyaWRlLCBhZ2VudCAvIHBsdWdpblxuICAgKiBkZWZhdWx0LCBvciBlbnYgdmFyKS4gV2hlbiBzZXQgaXQgd2lucyBvdmVyIGBtb2RlbENsYXNzYCBhbmQgYGZhbGxiYWNrc2AuXG4gICAqL1xuICBleHBsaWNpdD86IHN0cmluZztcbiAgLyoqXG4gICAqIEZ1enp5LW1hdGNoIGFuIGBleHBsaWNpdGAgbmFtZSBhZ2FpbnN0IHRoZSBsaXZlIGNhdGFsb2d1ZSBzbyBsb29zZSBuYW1lc1xuICAgKiBsaWtlIGBcImNsYXVkZSBzb25uZXRcImAgcmVzb2x2ZS4gRGVmYXVsdCBgdHJ1ZWAuIFdoZW4gYGZhbHNlYCB0aGUgZXhwbGljaXRcbiAgICogaW5wdXQgaXMgcmV0dXJuZWQgdmVyYmF0aW0gKERhdGFicmlja3Mgc3VyZmFjZXMgdGhlIGNhbm9uaWNhbCA0MDQgaWYgaXRcbiAgICogZG9lc24ndCBleGlzdCkuXG4gICAqL1xuICBmdXp6eT86IGJvb2xlYW47XG4gIC8qKiBGdXNlLmpzIHRocmVzaG9sZCBmb3J3YXJkZWQgdG8gdGhlIGZ1enp5IGBzZWFyY2hgIG1hdGNoICh7QGxpbmsgc2VhcmNoU2VydmluZ0VuZHBvaW50c30pLiAqL1xuICB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1aXJlIGEgbW9kZWwgdGhhdCBzdXBwb3J0cyBhIGNvbXBsZXRlIGZ1bmN0aW9uLXRvb2wgcm91bmQtdHJpcC4gKi9cbiAgcmVxdWlyZXNUb29scz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDaGF0IGNhcGFiaWxpdHkgY2xhc3MgdG8gcmVzb2x2ZSB3aGVuIG5vIGBleHBsaWNpdGAgaWQgaXMgZ2l2ZW4uIFRoZSBsaXZlXG4gICAqIGNhdGFsb2d1ZSBpcyBjbGFzc2lmaWVkIGJ5IGl0cyBGb3VuZGF0aW9uIE1vZGVsIEFQSSBzY29yZXMgYW5kIHRoZSB0b3BcbiAgICogYXZhaWxhYmxlIG1vZGVsIGluIHRoZSBjbGFzcyAoYW5kIHRoZSBjaGF0IGJhbmRzIGJlbG93IGl0KSB3aW5zLCBmYWxsaW5nXG4gICAqIGJhY2sgdG8gdGhlIGNsYXNzJ3Mgc21hbGwgc3RhdGljIGxpc3QuXG4gICAqL1xuICBtb2RlbENsYXNzPzogTW9kZWxDbGFzcztcbiAgLyoqXG4gICAqIE9wZXJhdG9yLXN1cHBsaWVkIGZhbGxiYWNrIGlkcyB0cmllZCAqZmlyc3QqIGluIHRoZSBuby1leHBsaWNpdCwgbm8tY2xhc3NcbiAgICogcGF0aCAoZS5nLiBhIHJlZ3VsYXRlZCB3b3Jrc3BhY2UgcGlubmVkIHRvIGFuIGFwcHJvdmVkIHN1YnNldCksIGFoZWFkIG9mXG4gICAqIHRoZSBhdXRvLWNsYXNzaWZpZWQgY2F0YWxvZ3VlLlxuICAgKi9cbiAgZmFsbGJhY2tzPzogcmVhZG9ubHkgc3RyaW5nW107XG4gIC8qKlxuICAgKiBSZWZ1c2UgdGhlIHN0YXRpYyBvZmZsaW5lIGZsb29yIHdoZW4gdGhlIGxpdmUgY2F0YWxvZ3VlIGhhcyBubyBtYXRjaC5cbiAgICogVXNlIGZvciB1bnBpbm5lZCBkZWZhdWx0cyB0aGF0IG11c3QgYWx3YXlzIG5hbWUgYSBjdXJyZW50bHkgYXZhaWxhYmxlXG4gICAqIGVuZHBvaW50LlxuICAgKi9cbiAgbGl2ZU9ubHk/OiBib29sZWFuO1xufVxuXG4vKiogT3V0Y29tZSBvZiB7QGxpbmsgcmVzb2x2ZU1vZGVsfTogdGhlIGNob3NlbiBpZCBwbHVzIGhvdyBpdCB3YXMgcmVhY2hlZC4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRNb2RlbFNlbGVjdGlvbiB7XG4gIG1vZGVsSWQ6IHN0cmluZztcbiAgc291cmNlOiBcImV4cGxpY2l0XCIgfCBcImZ1enp5LW1hdGNoXCIgfCBcImNsYXNzXCIgfCBcImZhbGxiYWNrXCI7XG59XG5cbi8qKiBJbnRlbnQgKyBjYXRhbG9ndWUga25vYnMgcGFzc2VkIHRvIHtAbGluayBzZWxlY3RNb2RlbH0uICovXG5leHBvcnQgaW50ZXJmYWNlIFNlbGVjdE1vZGVsSW5wdXQgZXh0ZW5kcyBSZXNvbHZlTW9kZWxJbnB1dCB7XG4gIC8qKiBUVEwgb3ZlcnJpZGUgZm9yIHRoZSBjYWNoZWQgYC9zZXJ2aW5nLWVuZHBvaW50c2AgbGlzdGluZywgaW4gbXMuICovXG4gIHR0bE1zPzogbnVtYmVyO1xufVxuXG4vKiogVFRMIG92ZXJyaWRlIG1lcmdlZCBpbnRvIGEge0BsaW5rIE1vZGVsUXVlcnl9IGZvciB7QGxpbmsgc2VhcmNoTW9kZWxzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VhcmNoTW9kZWxzSW5wdXQgZXh0ZW5kcyBNb2RlbFF1ZXJ5IHtcbiAgLyoqIFRUTCBvdmVycmlkZSBmb3IgdGhlIGNhY2hlZCBgL3NlcnZpbmctZW5kcG9pbnRzYCBsaXN0aW5nLCBpbiBtcy4gKi9cbiAgdHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogUmFuayB0aGUgbGl2ZSBjYXRhbG9ndWUgYWdhaW5zdCBhIHtAbGluayBNb2RlbFF1ZXJ5fSwgYmVzdC1maXJzdC5cbiAqXG4gKiBSdXN0IG93bnMgY2xhc3NpZmljYXRpb24sIGZ1enp5IHNjb3JpbmcsIGZhbWlseS12ZXJzaW9uIG9yZGVyaW5nLCBwcmVmZXJyZWRcbiAqIHZhcmlhbnRzLCBjbGFzcyBjZWlsaW5ncywgdG9vbCBmaWx0ZXJpbmcsIGFuZCByZXN1bHQgbGltaXRpbmcuIE5vZGUgcmV0YWluc1xuICogdGhlIGNhbGxlcidzIGVuZHBvaW50IG9iamVjdHMgc28gZmllbGRzIG91dHNpZGUgdGhlIHJhbmtpbmcgY29udHJhY3QgcmVtYWluXG4gKiBhdmFpbGFibGUgdW5jaGFuZ2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbG9va3VwTW9kZWxzKFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgcXVlcnk6IE1vZGVsUXVlcnkgPSB7fSxcbik6IFJhbmtlZE1vZGVsW10ge1xuICBjb25zdCBlbmRwb2ludHNCeU5hbWUgPSBuZXcgTWFwKGVuZHBvaW50cy5tYXAoKGVuZHBvaW50KSA9PiBbZW5kcG9pbnQubmFtZSwgZW5kcG9pbnRdKSk7XG4gIHJldHVybiByYW5rTW9kZWxzV2l0aFJ1c3QoZW5kcG9pbnRzLm1hcCh0b01vZGVsUnNFbmRwb2ludCksIHRvTW9kZWxSc1F1ZXJ5KHF1ZXJ5KSkubWFwKFxuICAgIChyYW5rZWQpID0+IHtcbiAgICAgIGNvbnN0IGVuZHBvaW50ID0gZW5kcG9pbnRzQnlOYW1lLmdldChyYW5rZWQuZW5kcG9pbnQubmFtZSk7XG4gICAgICBpZiAoIWVuZHBvaW50KSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUnVzdCBtb2RlbCByYW5raW5nIHJldHVybmVkIHVua25vd24gZW5kcG9pbnQgXCIke3JhbmtlZC5lbmRwb2ludC5uYW1lfVwiYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlbmRwb2ludCxcbiAgICAgICAgbW9kZWxDbGFzczogZnJvbU1vZGVsUnNDbGFzcyhyYW5rZWQubW9kZWxDbGFzcyksXG4gICAgICAgIC4uLihyYW5rZWQuc2NvcmUgIT09IHVuZGVmaW5lZCA/IHsgc2NvcmU6IHJhbmtlZC5zY29yZSB9IDoge30pLFxuICAgICAgfTtcbiAgICB9LFxuICApO1xufVxuXG4vKiogQ29udmVydCBhIHB1YmxpYyBtb2RlbCBxdWVyeSB0byB0aGUgZ2VuZXJhdGVkIFJ1c3QgcmFua2luZyBjb250cmFjdC4gKi9cbmZ1bmN0aW9uIHRvTW9kZWxSc1F1ZXJ5KHF1ZXJ5OiBNb2RlbFF1ZXJ5KTogTW9kZWxSc01vZGVsUXVlcnkge1xuICByZXR1cm4ge1xuICAgIHNlYXJjaDogcXVlcnkuc2VhcmNoLFxuICAgIG1vZGVsQ2xhc3M6IHF1ZXJ5Lm1vZGVsQ2xhc3MgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IE1PREVMX0NMQVNTX1RPX1JTW3F1ZXJ5Lm1vZGVsQ2xhc3NdLFxuICAgIHJlcXVpcmVzVG9vbHM6IHF1ZXJ5LnJlcXVpcmVzVG9vbHMgPz8gZmFsc2UsXG4gICAgaW5jbHVkZURlcHJlY2F0ZWQ6IGZhbHNlLFxuICAgIGxpbWl0OiBxdWVyeS5saW1pdCxcbiAgICB0aHJlc2hvbGQ6IHF1ZXJ5LnRocmVzaG9sZCxcbiAgfTtcbn1cblxuLyoqIENvbnZlcnQgYSBkaXNjb3ZlcmVkIGVuZHBvaW50IHRvIHRoZSBnZW5lcmF0ZWQgUnVzdCByYW5raW5nIGNvbnRyYWN0LiAqL1xuZnVuY3Rpb24gdG9Nb2RlbFJzRW5kcG9pbnQoZW5kcG9pbnQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnkpOiBNb2RlbFJzU2VydmluZ0VuZHBvaW50U3VtbWFyeSB7XG4gIHJldHVybiB7XG4gICAgbmFtZTogZW5kcG9pbnQubmFtZSxcbiAgICBkaXNwbGF5TmFtZTogZW5kcG9pbnQuZGlzcGxheU5hbWUsXG4gICAgdGFzazogZW5kcG9pbnQudGFzayxcbiAgICBzdGF0ZTogZW5kcG9pbnQuc3RhdGUsXG4gICAgZGVzY3JpcHRpb246IGVuZHBvaW50LmRlc2NyaXB0aW9uLFxuICAgIHN1cHBvcnRzVG9vbHM6IGVuZHBvaW50LnN1cHBvcnRzVG9vbHMsXG4gICAgcHJvZmlsZTogZW5kcG9pbnQucHJvZmlsZSxcbiAgICBtb2RlbENsYXNzOiBlbmRwb2ludC5jbGFzcyA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTU9ERUxfQ0xBU1NfVE9fUlNbZW5kcG9pbnQuY2xhc3NdLFxuICAgIHNlcnZpY2VOYW1lczogbmV3IE1hcChPYmplY3QuZW50cmllcyhlbmRwb2ludC5zZXJ2aWNlTmFtZXMgPz8ge30pKSxcbiAgICBtb2RlbFNlcnZpY2VOYW1lOiBlbmRwb2ludC5tb2RlbFNlcnZpY2VOYW1lLFxuICAgIHJlYXNvbmluZ0VmZm9ydHM6IFtdLFxuICAgIHN0YXR1czogeyBkZXByZWNhdGVkOiBlbmRwb2ludC5zdGF0dXM/LmRlcHJlY2F0ZWQgPz8gZmFsc2UgfSxcbiAgfTtcbn1cblxuLyoqIENvbnZlcnQgYSBnZW5lcmF0ZWQgUnVzdCBjbGFzcyB0byB0aGUgYnJvd3Nlci1zYWZlIHB1YmxpYyBlbnVtLiAqL1xuZnVuY3Rpb24gZnJvbU1vZGVsUnNDbGFzcyhtb2RlbENsYXNzOiBNb2RlbFJzTW9kZWxDbGFzcyk6IE1vZGVsQ2xhc3Mge1xuICBzd2l0Y2ggKG1vZGVsQ2xhc3MpIHtcbiAgICBjYXNlIE1vZGVsUnNNb2RlbENsYXNzLkNoYXRUaGlua2luZzpcbiAgICAgIHJldHVybiBtb2RlbC5Nb2RlbENsYXNzLkNoYXRUaGlua2luZztcbiAgICBjYXNlIE1vZGVsUnNNb2RlbENsYXNzLkNoYXRCYWxhbmNlZDpcbiAgICAgIHJldHVybiBtb2RlbC5Nb2RlbENsYXNzLkNoYXRCYWxhbmNlZDtcbiAgICBjYXNlIE1vZGVsUnNNb2RlbENsYXNzLkNoYXRGYXN0OlxuICAgICAgcmV0dXJuIG1vZGVsLk1vZGVsQ2xhc3MuQ2hhdEZhc3Q7XG4gICAgY2FzZSBNb2RlbFJzTW9kZWxDbGFzcy5FbWJlZGRpbmc6XG4gICAgICByZXR1cm4gbW9kZWwuTW9kZWxDbGFzcy5FbWJlZGRpbmc7XG4gIH1cbn1cblxuLyoqXG4gKiBDb2xsYXBzZSB7QGxpbmsgbG9va3VwTW9kZWxzfSB0byBhIHNpbmdsZSBpZDogdGhlIGNsb3Nlc3QgZW5kcG9pbnQgdG8gYHNlYXJjaGBcbiAqIGluIGEgY2F0YWxvZ3VlIHNuYXBzaG90LCBvciB0aGUgaW5wdXQgdmVyYmF0aW0gd2hlbiBub3RoaW5nIHNjb3JlcyB3aXRoaW4gdGhlXG4gKiB0aHJlc2hvbGQuXG4gKlxuICogVGhlIHJhbmstYmFzZWQgY291bnRlcnBhcnQgdG8gdGhlIEZ1c2Utb25seSB7QGxpbmsgcmVzb2x2ZU1vZGVsSWR9OiBlcXVhbFxuICogbWF0Y2ggc2NvcmVzIGFyZSBicm9rZW4gYnkgY2xhc3MgYW5kIHRoZW4gd2l0aGluLWNsYXNzIHZlcnNpb24sIHNvIGEgbG9vc2VcbiAqIGBcIm9wdXNcImAgcHJlZmVycyBgb3B1cy01YCBvdmVyIGBvcHVzLTQtN2AgaW5zdGVhZCBvZiBwaWNraW5nIHdoaWNoZXZlclxuICogc2libGluZyBGdXNlIGhhcHBlbmVkIHRvIG9yZGVyIGZpcnN0LiBSZXR1cm5pbmcgdGhlIGlucHV0IHVubWF0Y2hlZCAocmF0aGVyXG4gKiB0aGFuIGEgbmVhciBuZWlnaGJvdXIpIGlzIGRlbGliZXJhdGUgLSBhIGRlbGliZXJhdGUgZW5kcG9pbnQgaWQgaXMgbmV2ZXJcbiAqIHNpbGVudGx5IHJld3JpdHRlbiwgYW5kIERhdGFicmlja3Mgc3VyZmFjZXMgYSBjbGVhbiA0MDQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByYW5rTW9kZWxJZChcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIHNlYXJjaDogc3RyaW5nLFxuICBvcHRpb25zOiBSZXNvbHZlTW9kZWxPcHRpb25zID0ge30sXG4pOiBSZXNvbHZlZE1vZGVsIHtcbiAgY29uc3QgW3RvcF0gPSBsb29rdXBNb2RlbHMoZW5kcG9pbnRzLCB7XG4gICAgc2VhcmNoLFxuICAgIGxpbWl0OiAxLFxuICAgIC4uLihvcHRpb25zLnRocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8geyB0aHJlc2hvbGQ6IG9wdGlvbnMudGhyZXNob2xkIH0gOiB7fSksXG4gICAgLi4uKG9wdGlvbnMucmVxdWlyZXNUb29scyAhPT0gdW5kZWZpbmVkID8geyByZXF1aXJlc1Rvb2xzOiBvcHRpb25zLnJlcXVpcmVzVG9vbHMgfSA6IHt9KSxcbiAgfSk7XG4gIGlmICghdG9wKSByZXR1cm4geyBtb2RlbElkOiBzZWFyY2gsIG1hdGNoZWQ6IGZhbHNlIH07XG4gIHJldHVybiB7IG1vZGVsSWQ6IHRvcC5lbmRwb2ludC5uYW1lLCBtYXRjaGVkOiB0cnVlLCBzY29yZTogdG9wLnNjb3JlIH07XG59XG5cbi8qKlxuICoge0BsaW5rIHJhbmtNb2RlbElkfSBhZ2FpbnN0IGEgY2F0YWxvZ3VlIHRoZSBjYWxsZXIgbWF5IGJlIGhvbGRpbmcgc3RhbGU6XG4gKiBtYXRjaCB0aGUgbG9hZGVkIHNuYXBzaG90LCBhbmQgb24gYSBtaXNzIHJlbG9hZCBvbmNlIHdpdGggYGZvcmNlYCBhbmQgbWF0Y2hcbiAqIGFnYWluLiBUaGF0IHdheSBhIG1vZGVsIGRlcGxveWVkIGFmdGVyIHRoZSBjYXRhbG9ndWUgd2FzIGNhY2hlZCBzdGlsbFxuICogcmVzb2x2ZXMgb24gZmlyc3QgdXNlLCB3aXRob3V0IGEgcmVzdGFydCBhbmQgd2l0aG91dCBnaXZpbmcgdXAgY2FjaGluZy5cbiAqXG4gKiBUaGUgY2F0YWxvZ3VlIGFycml2ZXMgYXMgYSBsb2FkZXIgcmF0aGVyIHRoYW4gYSBjbGllbnQgc28gdGhlIGNhbGxlciBrZWVwc1xuICogb3duZXJzaGlwIG9mICpob3cqIGl0IGlzIGNhY2hlZCAtIHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30gYW5kIGl0c1xuICogYENhY2hlTWFuYWdlcmAsIGEgcGxhaW4gcHJvY2Vzcy1saWZldGltZSBmaWVsZCBpbiBhIENMSSwgb3IgYSB0ZXN0IGRvdWJsZS5cbiAqIE9ubHkgb25lIHJlbG9hZCBpcyBhdHRlbXB0ZWQ6IGEgZ2VudWluZWx5IHVua25vd24gbmFtZSBzaG91bGQgZmFpbCBmYXN0XG4gKiByYXRoZXIgdGhhbiByZS1saXN0IG9uIGV2ZXJ5IHJlcXVlc3QuXG4gKlxuICogQHBhcmFtIGxvYWQgLSBSZXR1cm5zIHRoZSBjYXRhbG9ndWU7IGBmb3JjZWAgYXNrcyBpdCB0byBieXBhc3MgaXRzIGNhY2hlLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmFua01vZGVsSWRMaXZlKFxuICBsb2FkOiAoZm9yY2U6IGJvb2xlYW4pID0+IFByb21pc2U8cmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPixcbiAgc2VhcmNoOiBzdHJpbmcsXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8UmVzb2x2ZWRNb2RlbD4ge1xuICBjb25zdCByZXNvbHZlZCA9IHJhbmtNb2RlbElkKGF3YWl0IGxvYWQoZmFsc2UpLCBzZWFyY2gsIG9wdGlvbnMpO1xuICBpZiAocmVzb2x2ZWQubWF0Y2hlZCkgcmV0dXJuIHJlc29sdmVkO1xuICByZXR1cm4gcmFua01vZGVsSWQoYXdhaXQgbG9hZCh0cnVlKSwgc2VhcmNoLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBSYW5rIGEgd29ya3NwYWNlJ3MgY2F0YWxvZ3VlIGluIG9uZSBjYWxsOiBsaXN0IGl0cyBgL3NlcnZpbmctZW5kcG9pbnRzYFxuICogKGNhY2hlZCkgYW5kIHJ1biB7QGxpbmsgbG9va3VwTW9kZWxzfSBvdmVyIHRoZSByZXN1bHQuIFRoZSBsaXN0IGNvdW50ZXJwYXJ0IHRvXG4gKiB7QGxpbmsgc2VsZWN0TW9kZWx9LCBmb3IgYSBjb25zdW1lciB0aGF0IHdhbnRzIHRoZSBmdWxsIHJhbmtlZCBzZXQgKGEgbW9kZWxcbiAqIHBpY2tlciwgYSBDTEkpIHJhdGhlciB0aGFuIGEgc2luZ2xlIGlkLiBDYXRhbG9ndWUgZmV0Y2hlcyBmYWlsIGxvdWQ6IG5ldHdvcmtcbiAqIC8gYXV0aCBlcnJvcnMgcHJvcGFnYXRlIHNvIHRoZSBjYWxsZXIgc2VlcyB0aGUgcmVhbCBTREsgbWVzc2FnZS5cbiAqXG4gKiBAcGFyYW0gaG9zdCAtIFdvcmtzcGFjZSBob3N0IHVzZWQgYXMgdGhlIGNhY2hlIGtleS4gUGFzcyB0aGUgdmFsdWUgcmVzb2x2ZWRcbiAqICAgZnJvbSBgY2xpZW50LmNvbmZpZy5nZXRIb3N0KClgLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VhcmNoTW9kZWxzKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgaW5wdXQ6IFNlYXJjaE1vZGVsc0lucHV0ID0ge30sXG4pOiBQcm9taXNlPFJhbmtlZE1vZGVsW10+IHtcbiAgY29uc3QgZW5kcG9pbnRzID0gYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHMoXG4gICAgY2xpZW50LFxuICAgIGhvc3QsXG4gICAgaW5wdXQudHRsTXMgIT09IHVuZGVmaW5lZCA/IHsgdHRsTXM6IGlucHV0LnR0bE1zIH0gOiB7fSxcbiAgKTtcbiAgcmV0dXJuIGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGlucHV0KTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgbW9kZWwgaWQgZm9yIGEgd29ya3NwYWNlIGluIG9uZSBjYWxsOiBsaXN0IGl0cyBgL3NlcnZpbmctZW5kcG9pbnRzYFxuICogKGNhY2hlZCkgYW5kIHJ1biB7QGxpbmsgcmVzb2x2ZU1vZGVsfSBvdmVyIHRoZSByZXN1bHQuIFRoaXMgaXMgdGhlIGVudHJ5XG4gKiBwb2ludCBmb3IgYW55IGNvbnN1bWVyIHRoYXQgaG9sZHMgYSBgV29ya3NwYWNlQ2xpZW50YCBhbmQganVzdCB3YW50cyBhIHVzYWJsZVxuICogbW9kZWwgbmFtZSAtIGEgTGFrZWZsb3cgam9iLCBhIG9uZS1vZmYgc2NyaXB0LCBvciB0aGUgTWFzdHJhIHBsdWdpbiBhbGlrZS5cbiAqXG4gKiBDaGVhcCBleGl0OiB3aGVuIGFuIGBleHBsaWNpdGAgbmFtZSBpcyBnaXZlbiwgYGZ1enp5YCBpcyBvZmYsIGFuZCB0b29sXG4gKiBjYXBhYmlsaXR5IGlzIG5vdCByZXF1aXJlZCwgdGhlIGNhdGFsb2d1ZSBpcyBuZXZlciBmZXRjaGVkLiBDYXRhbG9ndWVcbiAqIGZldGNoZXMgb3RoZXJ3aXNlIGZhaWwgbG91ZDogbmV0d29yayAvIGF1dGggZXJyb3JzIHByb3BhZ2F0ZSBzbyB0aGUgY2FsbGVyXG4gKiBzZWVzIHRoZSByZWFsIFNESyBtZXNzYWdlIGluc3RlYWQgb2YgYSBzaWxlbnQgZmFsbGJhY2suXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCB1c2VkIGFzIHRoZSBjYWNoZSBrZXkuIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkXG4gKiAgIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlbGVjdE1vZGVsKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgaW5wdXQ6IFNlbGVjdE1vZGVsSW5wdXQgPSB7fSxcbik6IFByb21pc2U8UmVzb2x2ZWRNb2RlbFNlbGVjdGlvbj4ge1xuICBpZiAoaW5wdXQuZXhwbGljaXQgIT09IHVuZGVmaW5lZCAmJiBpbnB1dC5mdXp6eSA9PT0gZmFsc2UgJiYgIWlucHV0LnJlcXVpcmVzVG9vbHMpIHtcbiAgICByZXR1cm4geyBtb2RlbElkOiBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImV4cGxpY2l0XCIgfTtcbiAgfVxuICBjb25zdCBlbmRwb2ludHMgPSBhd2FpdCBsaXN0U2VydmluZ0VuZHBvaW50cyhjbGllbnQsIGhvc3QsIHtcbiAgICAuLi4oaW5wdXQudHRsTXMgIT09IHVuZGVmaW5lZCA/IHsgdHRsTXM6IGlucHV0LnR0bE1zIH0gOiB7fSksXG4gIH0pO1xuICByZXR1cm4gcmVzb2x2ZU1vZGVsKGVuZHBvaW50cywgaW5wdXQpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBzaW5nbGUgbW9kZWwgaWQgZnJvbSB0aGUgbGl2ZSBjYXRhbG9ndWUgYW5kIGNhbGxlciBpbnRlbnQsXG4gKiBkZWxlZ2F0aW5nIHRoZSBsaXZlIHNlbGVjdGlvbiB0byB7QGxpbmsgbG9va3VwTW9kZWxzfSB3aXRoIGBsaW1pdDogMWAuXG4gKlxuICogMS4gKipFeHBsaWNpdCBhc2sqKjogd2l0aCBgZnV6enlgIG9mZiwgcmV0dXJuZWQgdmVyYmF0aW07IG90aGVyd2lzZVxuICogICAgZnV6enktcmFua2VkIHdpdGhpbiB0aGUgKG9wdGlvbmFsKSBjbGFzcyBjZWlsaW5nIGFuZCB0aGUgYmVzdCB0YWtlbixcbiAqICAgIGZhbGxpbmcgYmFjayB0byB0aGUgaW5wdXQgdmVyYmF0aW0gd2hlbiBub3RoaW5nIG1hdGNoZXMuXG4gKiAyLiAqKk5vIGV4cGxpY2l0IGFzayoqOiBhbiBvcGVyYXRvci1waW5uZWQgYGZhbGxiYWNrYCB0aGF0IGV4aXN0cyBpbiB0aGUgbGl2ZVxuICogICAgY2F0YWxvZ3VlIHdpbnMgZmlyc3QuIEEgY2xhc3MgcmVxdWVzdCByYW5rcyB3aXRoaW4gdGhhdCBjZWlsaW5nLiBBXG4gKiAgICBnZW5lcmFsIHJlcXVlc3QgcHJlZmVycyB0aGUgaGlnaGVzdC1yYW5rZWQgbGl2ZSBHUFQsIHRoZW4gYW55IHJhbmtlZCBsaXZlXG4gKiAgICBjaGF0IG1vZGVsLiBUaGUgc3RhdGljIHtAbGluayBGQUxMQkFDS19NT0RFTF9JRFN9IGZsb29yIGlzIHVzZWQgb25seSB3aGVuXG4gKiAgICB0aGUgY2F0YWxvZ3VlIHlpZWxkcyBub3RoaW5nIGluIHJhbmdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZU1vZGVsKFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgaW5wdXQ6IFJlc29sdmVNb2RlbElucHV0ID0ge30sXG4pOiBSZXNvbHZlZE1vZGVsU2VsZWN0aW9uIHtcbiAgaWYgKGlucHV0LmV4cGxpY2l0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoaW5wdXQuZnV6enkgPT09IGZhbHNlKSB7XG4gICAgICBpZiAoaW5wdXQucmVxdWlyZXNUb29scykgYXNzZXJ0VG9vbFN1cHBvcnQoZW5kcG9pbnRzLCBpbnB1dC5leHBsaWNpdCk7XG4gICAgICByZXR1cm4geyBtb2RlbElkOiBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImV4cGxpY2l0XCIgfTtcbiAgICB9XG4gICAgY29uc3QgW3RvcF0gPSBsb29rdXBNb2RlbHMoZW5kcG9pbnRzLCBidWlsZFF1ZXJ5KGlucHV0LCBpbnB1dC5leHBsaWNpdCkpO1xuICAgIGlmIChpbnB1dC5yZXF1aXJlc1Rvb2xzICYmICF0b3ApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm8gdG9vbC1jYXBhYmxlIG1vZGVsIG1hdGNoZXMgXCIke2lucHV0LmV4cGxpY2l0fVwiYCk7XG4gICAgfVxuICAgIHJldHVybiB7IG1vZGVsSWQ6IHRvcD8uZW5kcG9pbnQubmFtZSA/PyBpbnB1dC5leHBsaWNpdCwgc291cmNlOiBcImZ1enp5LW1hdGNoXCIgfTtcbiAgfVxuXG4gIC8vIE9wZXJhdG9yLXBpbm5lZCBmYWxsYmFja3Mgd2luIHdoZW4gcHJlc2VudCBhbmQgbGl2ZSAoZS5nLiBhIHJlZ3VsYXRlZFxuICAvLyB3b3Jrc3BhY2UgcmVzdHJpY3RlZCB0byBhbiBhcHByb3ZlZCBzdWJzZXQpLlxuICBpZiAoaW5wdXQubW9kZWxDbGFzcyA9PT0gdW5kZWZpbmVkICYmIGlucHV0LmZhbGxiYWNrcyAmJiBpbnB1dC5mYWxsYmFja3MubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IHByZXNlbnQgPSBuZXcgU2V0KFxuICAgICAgZW5kcG9pbnRzXG4gICAgICAgIC5maWx0ZXIoKGVuZHBvaW50KSA9PiAhaW5wdXQucmVxdWlyZXNUb29scyB8fCBjbGFzc2lmeS5lbmRwb2ludENhcGFiaWxpdGllcyhlbmRwb2ludCkudG9vbHMpXG4gICAgICAgIC5tYXAoKGVuZHBvaW50KSA9PiBlbmRwb2ludC5uYW1lKSxcbiAgICApO1xuICAgIGNvbnN0IHBpbm5lZCA9IGlucHV0LmZhbGxiYWNrcy5maW5kKChpZCkgPT4gcHJlc2VudC5oYXMoaWQpKTtcbiAgICBpZiAocGlubmVkKSByZXR1cm4geyBtb2RlbElkOiBwaW5uZWQsIHNvdXJjZTogXCJmYWxsYmFja1wiIH07XG4gIH1cblxuICBjb25zdCBzb3VyY2UgPSBpbnB1dC5tb2RlbENsYXNzICE9PSB1bmRlZmluZWQgPyBcImNsYXNzXCIgOiBcImZhbGxiYWNrXCI7XG4gIGlmIChpbnB1dC5tb2RlbENsYXNzID09PSB1bmRlZmluZWQpIHtcbiAgICBjb25zdCBbcHJlZmVycmVkXSA9IGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGJ1aWxkUXVlcnkoaW5wdXQsIERFRkFVTFRfTU9ERUxfRkFNSUxZX1NFQVJDSCkpO1xuICAgIGlmIChwcmVmZXJyZWQpIHJldHVybiB7IG1vZGVsSWQ6IHByZWZlcnJlZC5lbmRwb2ludC5uYW1lLCBzb3VyY2UgfTtcbiAgfVxuICBjb25zdCBbdG9wXSA9IGxvb2t1cE1vZGVscyhlbmRwb2ludHMsIGJ1aWxkUXVlcnkoaW5wdXQsIHVuZGVmaW5lZCkpO1xuICBpZiAodG9wKSByZXR1cm4geyBtb2RlbElkOiB0b3AuZW5kcG9pbnQubmFtZSwgc291cmNlIH07XG5cbiAgaWYgKGlucHV0LmxpdmVPbmx5KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTm8gbWF0Y2hpbmcgbGl2ZSBNb2RlbCBTZXJ2aW5nIGVuZHBvaW50IGlzIGF2YWlsYWJsZVwiKTtcbiAgfVxuXG4gIC8vIExpdmUgY2F0YWxvZ3VlIHlpZWxkZWQgbm90aGluZyBpbiByYW5nZTogd2FsayB0aGUgc3RhdGljIGZsb29yLlxuICBjb25zdCBmbG9vclNvdXJjZSA9XG4gICAgaW5wdXQubW9kZWxDbGFzcyAhPT0gdW5kZWZpbmVkID8gbW9kZWxzRm9yQ2xhc3MoaW5wdXQubW9kZWxDbGFzcykgOiAoaW5wdXQuZmFsbGJhY2tzID8/IFtdKTtcbiAgY29uc3QgZmxvb3IgPSBvYmplY3Quc2VxdWVuY2UoZmxvb3JTb3VyY2UpLmNvbmNhdChGQUxMQkFDS19NT0RFTF9JRFMpLmRpc3RpbmN0KCkudG9BcnJheSgpO1xuICBpZiAoaW5wdXQucmVxdWlyZXNUb29scykge1xuICAgIGNvbnN0IGF2YWlsYWJsZSA9IG5ldyBTZXQoXG4gICAgICBlbmRwb2ludHNcbiAgICAgICAgLmZpbHRlcigoZW5kcG9pbnQpID0+IGNsYXNzaWZ5LmVuZHBvaW50Q2FwYWJpbGl0aWVzKGVuZHBvaW50KS50b29scylcbiAgICAgICAgLm1hcCgoZW5kcG9pbnQpID0+IGVuZHBvaW50Lm5hbWUpLFxuICAgICk7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBmbG9vci5maW5kKChpZCkgPT4gYXZhaWxhYmxlLmhhcyhpZCkpO1xuICAgIGlmICghc2VsZWN0ZWQpIHRocm93IG5ldyBFcnJvcihcIk5vIHRvb2wtY2FwYWJsZSBtb2RlbCBpcyBhdmFpbGFibGVcIik7XG4gICAgcmV0dXJuIHsgbW9kZWxJZDogc2VsZWN0ZWQsIHNvdXJjZSB9O1xuICB9XG4gIHJldHVybiB7IG1vZGVsSWQ6IHBpY2tGaXJzdEF2YWlsYWJsZShmbG9vciwgZW5kcG9pbnRzKSwgc291cmNlIH07XG59XG5cbi8qKiBCdWlsZCBhIHtAbGluayBNb2RlbFF1ZXJ5fSBmcm9tIHtAbGluayBSZXNvbHZlTW9kZWxJbnB1dH0gZm9yIHRoZSBgbGltaXQ6IDFgIGRlbGVnYXRpb24uICovXG5mdW5jdGlvbiBidWlsZFF1ZXJ5KGlucHV0OiBSZXNvbHZlTW9kZWxJbnB1dCwgc2VhcmNoOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBNb2RlbFF1ZXJ5IHtcbiAgcmV0dXJuIHtcbiAgICAuLi4oc2VhcmNoICE9PSB1bmRlZmluZWQgPyB7IHNlYXJjaCB9IDoge30pLFxuICAgIC4uLihpbnB1dC5tb2RlbENsYXNzICE9PSB1bmRlZmluZWQgPyB7IG1vZGVsQ2xhc3M6IGlucHV0Lm1vZGVsQ2xhc3MgfSA6IHt9KSxcbiAgICAuLi4oaW5wdXQucmVxdWlyZXNUb29scyAhPT0gdW5kZWZpbmVkID8geyByZXF1aXJlc1Rvb2xzOiBpbnB1dC5yZXF1aXJlc1Rvb2xzIH0gOiB7fSksXG4gICAgLi4uKGlucHV0LnRocmVzaG9sZCAhPT0gdW5kZWZpbmVkID8geyB0aHJlc2hvbGQ6IGlucHV0LnRocmVzaG9sZCB9IDoge30pLFxuICAgIGxpbWl0OiAxLFxuICB9O1xufVxuXG4vKiogVGhyb3cgd2hlbiBhbiBleHBsaWNpdCBpZCBpcyBhYnNlbnQgb3Igbm90IHZlcmlmaWVkIGZvciBmdW5jdGlvbiB0b29scy4gKi9cbmZ1bmN0aW9uIGFzc2VydFRvb2xTdXBwb3J0KGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLCBtb2RlbElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgZW5kcG9pbnQgPSBlbmRwb2ludHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PT0gbW9kZWxJZCk7XG4gIGlmICghZW5kcG9pbnQgfHwgIWNsYXNzaWZ5LmVuZHBvaW50Q2FwYWJpbGl0aWVzKGVuZHBvaW50KS50b29scykge1xuICAgIHRocm93IG5ldyBFcnJvcihgTW9kZWwgXCIke21vZGVsSWR9XCIgZG9lcyBub3Qgc3VwcG9ydCBmdW5jdGlvbiB0b29sc2ApO1xuICB9XG59XG5cbi8qKlxuICogRmluZCB0aGUgZmlyc3QgaWQgaW4gYGNhbmRpZGF0ZXNgIHdob3NlIGVuZHBvaW50IGlzIHByZXNlbnQgaW4gYGVuZHBvaW50c2AuXG4gKiBSZXR1cm5zIHRoZSB0b3AgY2FuZGlkYXRlIHdoZW4gdGhlIHdvcmtzcGFjZSBoYXMgbm9uZSBvZiB0aGVtIHNvIGNhbGxlcnNcbiAqIGFsd2F5cyBnZXQgYSBzdHJpbmc7IGFuIG9mZmxpbmUgd29ya3NwYWNlIHRoZW4gcmVjZWl2ZXMgYSBjbGVhbiA0MDQgZnJvbVxuICogRGF0YWJyaWNrcyBpbnN0ZWFkIG9mIGEgbWFsZm9ybWVkIGNvbmZpZy5cbiAqL1xuZnVuY3Rpb24gcGlja0ZpcnN0QXZhaWxhYmxlKFxuICBjYW5kaWRhdGVzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4pOiBzdHJpbmcge1xuICBjb25zdCBwcmVzZW50ID0gbmV3IFNldChlbmRwb2ludHMubWFwKChlKSA9PiBlLm5hbWUpKTtcbiAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgY2FuZGlkYXRlcykge1xuICAgIGlmIChwcmVzZW50LmhhcyhjYW5kaWRhdGUpKSByZXR1cm4gY2FuZGlkYXRlO1xuICB9XG4gIHJldHVybiBjYW5kaWRhdGVzWzBdID8/IEZBTExCQUNLX01PREVMX0lEU1swXSE7XG59XG4iXX0=
|
package/lib/src/serving.js
CHANGED
|
@@ -25,6 +25,7 @@ import { error, log, string } from "@dbx-tools/shared-core";
|
|
|
25
25
|
import { classify, display, model, } from "@dbx-tools/shared-model";
|
|
26
26
|
import Fuse from "fuse.js";
|
|
27
27
|
import { MODEL_CLASS_ORDER } from "./classes.js";
|
|
28
|
+
import { modelFamily, modelReasoningEfforts } from "./policy.js";
|
|
28
29
|
const { ModelClass } = model;
|
|
29
30
|
const logger = log.logger("model/serving");
|
|
30
31
|
/** Default TTL for the in-memory endpoint cache. Matches the Databricks SDK's session lifetime budget. */
|
|
@@ -82,16 +83,20 @@ export async function listServingEndpointsUncached(client) {
|
|
|
82
83
|
if (!ep.name)
|
|
83
84
|
continue;
|
|
84
85
|
const profile = extractProfile(ep);
|
|
86
|
+
const family = modelFamily(ep.name);
|
|
87
|
+
const reasoningEfforts = modelReasoningEfforts(ep.name);
|
|
85
88
|
out.push({
|
|
86
89
|
name: ep.name,
|
|
87
90
|
// Prefer a Databricks-provided human name (a display-name tag or an
|
|
88
91
|
// external-model name); else derive a title-cased label from the id.
|
|
89
92
|
displayName: display.toModelDisplayName(ep.name, providedDisplayName(ep)),
|
|
93
|
+
...(family !== undefined ? { family } : {}),
|
|
90
94
|
...(ep.task !== undefined ? { task: ep.task } : {}),
|
|
91
95
|
...(ep.state?.ready !== undefined ? { state: String(ep.state.ready) } : {}),
|
|
92
96
|
...(ep.description !== undefined ? { description: ep.description } : {}),
|
|
93
97
|
supportsTools: classify.supportsToolsByFamily(ep.name),
|
|
94
98
|
...(profile ? { profile } : {}),
|
|
99
|
+
...(reasoningEfforts.length > 0 ? { reasoningEfforts } : {}),
|
|
95
100
|
});
|
|
96
101
|
}
|
|
97
102
|
return out;
|
|
@@ -284,4 +289,4 @@ export function resolveModelId(input, endpoints, options = {}) {
|
|
|
284
289
|
}
|
|
285
290
|
return { modelId: input, matched: false };
|
|
286
291
|
}
|
|
287
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbEQsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUNMLFFBQVEsRUFDUixPQUFPLEVBQ1AsS0FBSyxHQUdOLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxJQUFJLE1BQU0sU0FBUyxDQUFDO0FBRTNCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVqRCxNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBRTdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7QUFTM0MsMEdBQTBHO0FBQzFHLE1BQU0sQ0FBQyxNQUFNLDBCQUEwQixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXhELDZFQUE2RTtBQUM3RSxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFFM0MsZ0VBQWdFO0FBQ2hFLE1BQU0sbUJBQW1CLEdBQUcsbUJBQW1CLENBQUM7QUFFaEQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sZUFBZSxHQUFHLGNBQWMsQ0FBQztBQVd2Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsb0JBQW9CLENBQ3hDLE1BQTJCLEVBQzNCLElBQVksRUFDWixVQUF1QyxFQUFFO0lBRXpDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxJQUFJ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S0FBSztLQUN2QixDQUFDLENBQUM7SUFDSCxPQUFPLElBQUk7U0FDUixNQUFNLENBQUMsS0FBSyxDQUFDO1NBQ2IsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDLElBQUksU0FBUyxDQUFDO1NBQzFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUM3RCxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsS0FBYSxFQUNiLFNBQTRDLEVBQzVDLFVBQStCLEVBQUU7SUFFakMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLHNCQUFzQixDQUFDLEtBQUssRUFBRSxTQUFTLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDakUsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNULE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzNFLENBQUM7SUFDRCxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7QUFDNUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogTGl2ZSBEYXRhYnJpY2tzIE1vZGVsIFNlcnZpbmcgY2F0YWxvZ3VlIGFjY2Vzcy5cbiAqXG4gKiBMaXN0cyB0aGUgd29ya3NwYWNlJ3MgYC9zZXJ2aW5nLWVuZHBvaW50c2Agb25jZSBwZXIgaG9zdCBhbmQgY2FjaGVzIHRoZVxuICogcmVzdWx0IHdpdGggYSBUVEwgdmlhIEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgLCB3aXRoIGNvbmN1cnJlbnQgY2FsbGVyc1xuICogc2hhcmluZyBvbmUgaW4tZmxpZ2h0IHByb21pc2UgKHRoZSBjb2FsZXNjaW5nIHBhdHRlcm4gb2YgUHl0aG9uJ3NcbiAqIGBjYWNoZXRvb2xzLWFzeW5jYCkuIFN1cmZhY2VzIGVhY2ggZW5kcG9pbnQgYXMgYSBzdGFibGVcbiAqIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5fSAtIGluY2x1ZGluZyB0aGUgRm91bmRhdGlvbiBNb2RlbCBBUElcbiAqIGBxdWFsaXR5YCAvIGBzcGVlZGAgLyBgY29zdGAgcHJvZmlsZSB3aGVuIHByZXNlbnQsIHRoZSBjbGFzc2lmaWVkXG4gKiB7QGxpbmsgTW9kZWxDbGFzc30sIGFuZCAoZm9yIGVtYmVkZGluZyBlbmRwb2ludHMpIHRoZSBtZWFzdXJlZCB2ZWN0b3JcbiAqIGBkaW1lbnNpb25gIC0gYW5kIHNuYXBzIGxvb3NlLCBodW1hbi10eXBlZCBuYW1lcyB0byByZWFsIGVuZHBvaW50IGlkc1xuICogdGhyb3VnaCBgZnVzZS5qc2AgZXh0ZW5kZWQgc2VhcmNoIHNvIHRva2VucyBsaWtlIGBcImNsYXVkZSBzb25uZXRcImAgcmVzb2x2ZSB0b1xuICogYGRhdGFicmlja3MtY2xhdWRlLXNvbm5ldC00LTZgLlxuICpcbiAqIFRoZSBjbGFzcyBzdGFtcCBhbmQgZW1iZWRkaW5nIGRpbWVuc2lvbiBhcmUgY29tcHV0ZWQgb25jZSBwZXIgY2FjaGUgbG9hZDpcbiAqIGV2ZXJ5IGVtYmVkZGluZyBlbmRwb2ludCBpcyBcInBpbmdlZFwiIGluIHBhcmFsbGVsIGFuZCB0aGUgcmVzdWx0aW5nIHZlY3RvclxuICogbGVuZ3RoIHJlY29yZGVkLCBzbyB0aGUgY29zdCBpcyBwYWlkIG9uIGEgY2FjaGUgbWlzcywgbm90IHBlciByZWFkLiBUaGUgcGluZ1xuICogaXMgYmVzdC1lZmZvcnQgLSBhIGZhaWx1cmUgbG9ncyBhdCBkZWJ1ZyBhbmQgbGVhdmVzIGBkaW1lbnNpb25gIHVuc2V0IHJhdGhlclxuICogdGhhbiBmYWlsaW5nIHRoZSB3aG9sZSBsaXN0aW5nLlxuICpcbiAqIEBtb2R1bGVcbiAqL1xuXG5pbXBvcnQgeyBDYWNoZU1hbmFnZXIgfSBmcm9tIFwiQGRhdGFicmlja3MvYXBwa2l0XCI7XG5pbXBvcnQgeyBhcHBraXQgfSBmcm9tIFwiQGRieC10b29scy9hcHBraXRcIjtcbmltcG9ydCB7IGVycm9yLCBsb2csIHN0cmluZyB9IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlXCI7XG5pbXBvcnQge1xuICBjbGFzc2lmeSxcbiAgZGlzcGxheSxcbiAgbW9kZWwsXG4gIHR5cGUgTW9kZWxQcm9maWxlLFxuICB0eXBlIFNlcnZpbmdFbmRwb2ludFN1bW1hcnksXG59IGZyb20gXCJAZGJ4LXRvb2xzL3NoYXJlZC1tb2RlbFwiO1xuaW1wb3J0IEZ1c2UgZnJvbSBcImZ1c2UuanNcIjtcblxuaW1wb3J0IHsgTU9ERUxfQ0xBU1NfT1JERVIgfSBmcm9tIFwiLi9jbGFzc2VzLnRzXCI7XG5cbmNvbnN0IHsgTW9kZWxDbGFzcyB9ID0gbW9kZWw7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtb2RlbC9zZXJ2aW5nXCIpO1xuXG4vKipcbiAqIFN0cnVjdHVyYWwgdHlwZSBmb3IgdGhlIERhdGFicmlja3Mgd29ya3NwYWNlIGNsaWVudCwgcmUtZXhwb3J0ZWQgc28gdGhlIHJlc3RcbiAqIG9mIHRoaXMgcGFja2FnZSBjYW4ga2VlcCBpbXBvcnRpbmcgaXQgZnJvbSBoZXJlLiBTZWVcbiAqIGBhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZWAgKG5vZGUtYXBwa2l0KSBmb3IgdGhlIGNhbm9uaWNhbCBkZWZpbml0aW9uLlxuICovXG5leHBvcnQgdHlwZSBXb3Jrc3BhY2VDbGllbnRMaWtlID0gUGljazxhcHBraXQuV29ya3NwYWNlQ2xpZW50TGlrZSwgXCJzZXJ2aW5nRW5kcG9pbnRzXCI+O1xuXG4vKiogRGVmYXVsdCBUVEwgZm9yIHRoZSBpbi1tZW1vcnkgZW5kcG9pbnQgY2FjaGUuIE1hdGNoZXMgdGhlIERhdGFicmlja3MgU0RLJ3Mgc2Vzc2lvbiBsaWZldGltZSBidWRnZXQuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NT0RFTF9DQUNIRV9UVExfTVMgPSA1ICogNjAgKiAxMDAwO1xuXG4vKiogRGVmYXVsdCBGdXNlLmpzIHNjb3JlIHRocmVzaG9sZCBiZWxvdyB3aGljaCBhIGZ1enp5IG1hdGNoIGlzIGFjY2VwdGVkLiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRlVaWllfVEhSRVNIT0xEID0gMC40O1xuXG4vKiogQ2FjaGUga2V5IHBhcnRzIHVuZGVyIHdoaWNoIGVuZHBvaW50IGxpc3RpbmdzIGFyZSBzdG9yZWQuICovXG5jb25zdCBDQUNIRV9LRVlfTkFNRVNQQUNFID0gXCJzZXJ2aW5nLWVuZHBvaW50c1wiO1xuXG4vKipcbiAqIFN0YWJsZSBgdXNlcktleWAgYXJnIGZvciBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyLmdldE9yRXhlY3V0ZWAuIEVuZHBvaW50XG4gKiB2aXNpYmlsaXR5IGlzIGVmZmVjdGl2ZWx5IHdvcmtzcGFjZS1zY29wZWQgKHdlIGNhY2hlIGJ5IGhvc3QgaW4gdGhlIGtleVxuICogcGFydHMpLCBzbyBhIHNpbmdsZSBzaGFyZWQga2V5IGxldHMgZXZlcnkgdXNlciBvZiB0aGUgc2FtZSB3b3Jrc3BhY2Ugc2hhcmVcbiAqIG9uZSBjYWNoZWQgZmV0Y2ggYW5kIGNvYWxlc2NlIG9uIHRoZSBpbi1mbGlnaHQgcHJvbWlzZS4gUGVybWlzc2lvbnMgY2FuXG4gKiBkaWZmZXIgaW4gdGhlb3J5LCBidXQgdGhlIEZvdW5kYXRpb24gTW9kZWwgQVBJIGNhdGFsb2d1ZSBpcyB0aGUgc2FtZSB2aWV3IGZvclxuICogZXZlcnkgY2FsbGVyLlxuICovXG5jb25zdCBTSEFSRURfVVNFUl9LRVkgPSBcIm1vZGVsLXNoYXJlZFwiO1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIGxpc3RTZXJ2aW5nRW5kcG9pbnRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdFNlcnZpbmdFbmRwb2ludHNPcHRpb25zIHtcbiAgLyoqXG4gICAqIE92ZXJyaWRlIHRoZSBkZWZhdWx0IGNhY2hlIFRUTCBmb3IgdGhpcyBjYWxsLCBpbiBtaWxsaXNlY29uZHMuIEZvcndhcmRlZCB0b1xuICAgKiBgQ2FjaGVNYW5hZ2VyYCBhcyBzZWNvbmRzLlxuICAgKi9cbiAgdHRsTXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogTGlzdCBNb2RlbCBTZXJ2aW5nIGVuZHBvaW50cyBmb3IgdGhlIHdvcmtzcGFjZSBvd25pbmcgYGNsaWVudGAsIHJvdXRlZFxuICogdGhyb3VnaCBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyYC4gVGhlIG1hbmFnZXIgZ2l2ZXMgdXMgZXZlcnl0aGluZ1xuICogYGNhY2hldG9vbHMuVFRMQ2FjaGVgIHByb3ZpZGVzIHBsdXMgd2hhdCBgY2FjaGV0b29scy1hc3luY2AgYWRkcyBvbiB0b3A6XG4gKiBwZXItZW50cnkgVFRMLCBpbi1mbGlnaHQgcmVxdWVzdCBjb2FsZXNjaW5nIChjb25jdXJyZW50IGNhbGxlcnMgc2hhcmUgb25lXG4gKiBmZXRjaCB2aWEgdGhlIG1hbmFnZXIncyBpbnRlcm5hbCBgaW5GbGlnaHRSZXF1ZXN0c2AgbWFwKSwgYm91bmRlZCBzaXplLFxuICogdGVsZW1ldHJ5IHNwYW5zIChgY2FjaGUuZ2V0T3JFeGVjdXRlYCksIGFuZCBvcHRpb25hbCBMYWtlYmFzZSBwZXJzaXN0ZW5jZSBzb1xuICogdGhlIGNhdGFsb2d1ZSBzdXJ2aXZlcyByZXN0YXJ0cyB3aGVuIHRoZSBsYWtlYmFzZSBwbHVnaW4gaXMgd2lyZWQgdXAuXG4gKlxuICogUmV0dXJucyBwbGFpbiB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeX0gb2JqZWN0cyAoYSBzdGFibGUgc3Vic2V0IG9mIHRoZVxuICogU0RLIHR5cGUpIHNvIGNhY2hlIGhpdHMgbmV2ZXIgZXhwb3NlIHN0YWxlIFNESyBpbnRlcm5hbHMuIEVycm9ycyBmcm9tXG4gKiBgQ2FjaGVNYW5hZ2VyYCBvciB0aGUgU0RLIGZldGNoIHByb3BhZ2F0ZSB0byB0aGUgY2FsbGVyIC0gd2UgZG9uJ3Qgc3dhbGxvd1xuICogdGhlbSBzbyB1c2VycyBzZWUgdGhlIHJlYWwgYXV0aCAvIG5ldHdvcmsgaXNzdWUuXG4gKlxuICogQHBhcmFtIGhvc3QgLSBXb3Jrc3BhY2UgaG9zdCB1c2VkIGFzIHRoZSBjYWNoZSBrZXkuIFBhc3MgdGhlIHZhbHVlIHJlc29sdmVkXG4gKiAgIGZyb20gYGNsaWVudC5jb25maWcuZ2V0SG9zdCgpYCBzbyBtdWx0aS1ob3N0IGFwcHMgc2hhcmUgb25lIGVudHJ5IHBlclxuICogICB3b3Jrc3BhY2UuXG4gKiBAcGFyYW0gb3B0aW9ucy50dGxNcyAtIE92ZXJyaWRlIHRoZSBkZWZhdWx0IFRUTCBqdXN0IGZvciB0aGlzIGNhbGwuIEZvcndhcmRlZFxuICogICB0byBgQ2FjaGVNYW5hZ2VyYCBhcyBzZWNvbmRzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGlzdFNlcnZpbmdFbmRwb2ludHMoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbiAgaG9zdDogc3RyaW5nLFxuICBvcHRpb25zOiBMaXN0U2VydmluZ0VuZHBvaW50c09wdGlvbnMgPSB7fSxcbik6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gIGNvbnN0IHR0bFNlYyA9IE1hdGgubWF4KDEsIE1hdGgucm91bmQoKG9wdGlvbnMudHRsTXMgPz8gREVGQVVMVF9NT0RFTF9DQUNIRV9UVExfTVMpIC8gMTAwMCkpO1xuICByZXR1cm4gQ2FjaGVNYW5hZ2VyLmdldEluc3RhbmNlU3luYygpLmdldE9yRXhlY3V0ZShcbiAgICBbQ0FDSEVfS0VZX05BTUVTUEFDRSwgaG9zdF0sXG4gICAgKCkgPT4gZmV0Y2hFbmRwb2ludHMoY2xpZW50KSxcbiAgICBTSEFSRURfVVNFUl9LRVksXG4gICAgeyB0dGw6IHR0bFNlYyB9LFxuICApO1xufVxuXG4vKipcbiAqIExpc3QgdGhlIHdvcmtzcGFjZSdzIHNlcnZpbmcgZW5kcG9pbnRzIGFzIG1pbmltYWxcbiAqIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5fSBvYmplY3RzIHN0cmFpZ2h0IGZyb20gdGhlIFNESzogbm8gY2FjaGluZywgYW5kXG4gKiBub25lIG9mIHRoZSBjYWNoZS1sb2FkIGVucmljaG1lbnQgKHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30gYWRkcyB0aGVcbiAqIHtAbGluayBNb2RlbENsYXNzfSBzdGFtcCBhbmQgdGhlIGVtYmVkZGluZy1kaW1lbnNpb24gcHJvYmUpLiBVc2UgdGhpcyBmb3IgYVxuICogb25lLXNob3QsIGRlcGVuZGVuY3ktbGlnaHQgbGlzdGluZyAtIGUuZy4gYSBDTEkgdGhhdCBvbmx5IG5lZWRzIG5hbWVzL3Rhc2tzXG4gKiBmb3IgZnV6enkgcmVzb2x1dGlvbiBhbmQgZG9lc24ndCB3YW50IEFwcEtpdCdzIGBDYWNoZU1hbmFnZXJgIG9yIHRoZVxuICogcGVyLWVtYmVkZGluZyBwaW5nIGNvc3QuIFByZWZlciB7QGxpbmsgbGlzdFNlcnZpbmdFbmRwb2ludHN9IGZvciB0aGUgY2FjaGVkLFxuICogZW5yaWNoZWQgdmlldy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RTZXJ2aW5nRW5kcG9pbnRzVW5jYWNoZWQoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbik6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gIGNvbnN0IG91dDogU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdID0gW107XG4gIGZvciBhd2FpdCAoY29uc3QgZXAgb2YgY2xpZW50LnNlcnZpbmdFbmRwb2ludHMubGlzdCgpKSB7XG4gICAgaWYgKCFlcC5uYW1lKSBjb250aW51ZTtcbiAgICBjb25zdCBwcm9maWxlID0gZXh0cmFjdFByb2ZpbGUoZXApO1xuICAgIG91dC5wdXNoKHtcbiAgICAgIG5hbWU6IGVwLm5hbWUsXG4gICAgICAvLyBQcmVmZXIgYSBEYXRhYnJpY2tzLXByb3ZpZGVkIGh1bWFuIG5hbWUgKGEgZGlzcGxheS1uYW1lIHRhZyBvciBhblxuICAgICAgLy8gZXh0ZXJuYWwtbW9kZWwgbmFtZSk7IGVsc2UgZGVyaXZlIGEgdGl0bGUtY2FzZWQgbGFiZWwgZnJvbSB0aGUgaWQuXG4gICAgICBkaXNwbGF5TmFtZTogZGlzcGxheS50b01vZGVsRGlzcGxheU5hbWUoZXAubmFtZSwgcHJvdmlkZWREaXNwbGF5TmFtZShlcCkpLFxuICAgICAgLi4uKGVwLnRhc2sgIT09IHVuZGVmaW5lZCA/IHsgdGFzazogZXAudGFzayB9IDoge30pLFxuICAgICAgLi4uKGVwLnN0YXRlPy5yZWFkeSAhPT0gdW5kZWZpbmVkID8geyBzdGF0ZTogU3RyaW5nKGVwLnN0YXRlLnJlYWR5KSB9IDoge30pLFxuICAgICAgLi4uKGVwLmRlc2NyaXB0aW9uICE9PSB1bmRlZmluZWQgPyB7IGRlc2NyaXB0aW9uOiBlcC5kZXNjcmlwdGlvbiB9IDoge30pLFxuICAgICAgc3VwcG9ydHNUb29sczogY2xhc3NpZnkuc3VwcG9ydHNUb29sc0J5RmFtaWx5KGVwLm5hbWUpLFxuICAgICAgLi4uKHByb2ZpbGUgPyB7IHByb2ZpbGUgfSA6IHt9KSxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIFB1bGwgYSBEYXRhYnJpY2tzLXByb3ZpZGVkIGh1bWFuIG5hbWUgb2ZmIGEgc2VydmluZyBlbmRwb2ludCwgaWYgYW55OlxuICogYSBgZGlzcGxheV9uYW1lYCAvIGBkaXNwbGF5TmFtZWAgLyBgbmFtZWAgdGFnIGZpcnN0LCB0aGVuIGFuXG4gKiBleHRlcm5hbC1tb2RlbCBgbmFtZWAgZnJvbSB0aGUgc2VydmVkLWVudGl0eSBjb25maWcuIFJldHVybnMgYG51bGxgXG4gKiB3aGVuIHRoZSBlbmRwb2ludCBjYXJyaWVzIG5vIGV4cGxpY2l0IG5hbWUgKHRoZSBjb21tb24gY2FzZSBmb3JcbiAqIEZvdW5kYXRpb24gTW9kZWwgQVBJIGVuZHBvaW50cyksIHNvIHRoZSBjYWxsZXIgZmFsbHMgYmFjayB0byBkZXJpdmluZ1xuICogb25lIGZyb20gdGhlIGlkLlxuICovXG5mdW5jdGlvbiBwcm92aWRlZERpc3BsYXlOYW1lKGVwOiB7XG4gIHRhZ3M/OiBBcnJheTx7IGtleTogc3RyaW5nOyB2YWx1ZT86IHN0cmluZyB9PjtcbiAgY29uZmlnPzogeyBzZXJ2ZWRfZW50aXRpZXM/OiBBcnJheTx7IGV4dGVybmFsX21vZGVsPzogeyBuYW1lPzogc3RyaW5nIH0gfT4gfTtcbn0pOiBzdHJpbmcgfCBudWxsIHtcbiAgY29uc3QgdGFnID0gZXAudGFncz8uZmluZChcbiAgICAodCkgPT4gdC5rZXkgPT09IFwiZGlzcGxheV9uYW1lXCIgfHwgdC5rZXkgPT09IFwiZGlzcGxheU5hbWVcIiB8fCB0LmtleSA9PT0gXCJuYW1lXCIsXG4gICk7XG4gIGNvbnN0IGZyb21UYWcgPSBzdHJpbmcudHJpbVRvTnVsbCh0YWc/LnZhbHVlKTtcbiAgaWYgKGZyb21UYWcpIHJldHVybiBmcm9tVGFnO1xuICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlcC5jb25maWc/LnNlcnZlZF9lbnRpdGllcyA/PyBbXSkge1xuICAgIGNvbnN0IGV4dGVybmFsID0gc3RyaW5nLnRyaW1Ub051bGwoZW50aXR5LmV4dGVybmFsX21vZGVsPy5uYW1lKTtcbiAgICBpZiAoZXh0ZXJuYWwpIHJldHVybiBleHRlcm5hbDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hFbmRwb2ludHMoY2xpZW50OiBXb3Jrc3BhY2VDbGllbnRMaWtlKTogUHJvbWlzZTxTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10+IHtcbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3Qgb3V0ID0gYXdhaXQgbGlzdFNlcnZpbmdFbmRwb2ludHNVbmNhY2hlZChjbGllbnQpO1xuICBzdGFtcE1vZGVsQ2xhc3NlcyhvdXQpO1xuICBhd2FpdCBtZWFzdXJlRW1iZWRkaW5nRGltZW5zaW9ucyhjbGllbnQsIG91dCk7XG4gIGxvZ2dlci5kZWJ1ZyhcImxpc3RlZFwiLCB7IGNvdW50OiBvdXQubGVuZ3RoLCBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQgfSk7XG4gIHJldHVybiBvdXQ7XG59XG5cbi8qKlxuICogU3RhbXAgZWFjaCBzdW1tYXJ5J3Mge0BsaW5rIFNlcnZpbmdFbmRwb2ludFN1bW1hcnkuY2xhc3N9IGZyb20gdGhlIHJlbGF0aXZlXG4gKiBjbGFzc2lmaWNhdGlvbiBvZiB0aGUgd2hvbGUgc2V0LiBNdXRhdGVzIGBzdW1tYXJpZXNgIGluIHBsYWNlLiBFbmRwb2ludHMgdGhlXG4gKiBjbGFzc2lmaWVyIGRvZXNuJ3QgcmVjb2duaXplIChjdXN0b20sIHVuc2NvcmVkLCBub24tTExNKSBhcmUgbGVmdCB3aXRob3V0IGFcbiAqIGNsYXNzLlxuICovXG5mdW5jdGlvbiBzdGFtcE1vZGVsQ2xhc3NlcyhzdW1tYXJpZXM6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSk6IHZvaWQge1xuICBjb25zdCBidWNrZXRzID0gY2xhc3NpZnkuY2xhc3NpZnlFbmRwb2ludHMoc3VtbWFyaWVzKTtcbiAgY29uc3QgY2xhc3NPZiA9IG5ldyBNYXA8c3RyaW5nLCBtb2RlbC5Nb2RlbENsYXNzPigpO1xuICBmb3IgKGNvbnN0IGNscyBvZiBNT0RFTF9DTEFTU19PUkRFUikge1xuICAgIGZvciAoY29uc3QgZXAgb2YgYnVja2V0c1tjbHNdKSBjbGFzc09mLnNldChlcC5uYW1lLCBjbHMpO1xuICB9XG4gIGZvciAoY29uc3Qgc3VtbWFyeSBvZiBzdW1tYXJpZXMpIHtcbiAgICBjb25zdCBjbHMgPSBjbGFzc09mLmdldChzdW1tYXJ5Lm5hbWUpO1xuICAgIGlmIChjbHMgIT09IHVuZGVmaW5lZCkgc3VtbWFyeS5jbGFzcyA9IGNscztcbiAgfVxufVxuXG4vKipcbiAqIE1lYXN1cmUgdGhlIGVtYmVkZGluZyB2ZWN0b3IgZGltZW5zaW9uIG9mIGV2ZXJ5IHtAbGluayBNb2RlbENsYXNzLkVtYmVkZGluZ31cbiAqIGVuZHBvaW50IGJ5IHBpbmdpbmcgaXQgb25jZSwgYWxsIGluIHBhcmFsbGVsLiBNdXRhdGVzIHRoZSBtYXRjaGluZyBzdW1tYXJpZXNcbiAqIGluIHBsYWNlIHdpdGggdGhlIHJlc3VsdGluZyBgZGltZW5zaW9uYC4gUnVucyBvbmx5IG9uIGEgY2FjaGUgbWlzcyAoaXQnc1xuICogY2FsbGVkIGZyb20ge0BsaW5rIGZldGNoRW5kcG9pbnRzfSksIHNvIHRoZSBwcm9iZSBjb3N0IGlzIGFtb3J0aXplZCBhY3Jvc3MgdGhlXG4gKiBjYWNoZWQgVFRMIHdpbmRvdy4gUGVyLWVuZHBvaW50IGZhaWx1cmVzIGFyZSBzd2FsbG93ZWQgKGxvZ2dlZCBhdCB3YXJuKSBzb1xuICogb25lIHVucmVhY2hhYmxlIGVtYmVkZGluZyBtb2RlbCBuZXZlciBmYWlscyB0aGUgbGlzdGluZy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gbWVhc3VyZUVtYmVkZGluZ0RpbWVuc2lvbnMoXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbiAgc3VtbWFyaWVzOiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgc3VtbWFyaWVzXG4gICAgICAuZmlsdGVyKChzKSA9PiBzLmNsYXNzID09PSBNb2RlbENsYXNzLkVtYmVkZGluZylcbiAgICAgIC5tYXAoYXN5bmMgKHN1bW1hcnkpID0+IHtcbiAgICAgICAgY29uc3QgZGltZW5zaW9uID0gYXdhaXQgcGluZ0VtYmVkZGluZ0RpbWVuc2lvbihjbGllbnQsIHN1bW1hcnkubmFtZSk7XG4gICAgICAgIGlmIChkaW1lbnNpb24gIT09IHVuZGVmaW5lZCkgc3VtbWFyeS5kaW1lbnNpb24gPSBkaW1lbnNpb247XG4gICAgICB9KSxcbiAgKTtcbn1cblxuLyoqXG4gKiBCZXN0LWVmZm9ydCBlbWJlZGRpbmcgZGltZW5zaW9uIHByb2JlOiBxdWVyeSBgbmFtZWAgd2l0aCBhIHRpbnkgYFwicGluZ1wiYFxuICogaW5wdXQgYW5kIHJldHVybiB0aGUgbGVuZ3RoIG9mIHRoZSByZXR1cm5lZCB2ZWN0b3IuIFJldHVybnMgYHVuZGVmaW5lZGAgKGFuZFxuICogbG9ncyBhdCB3YXJuKSB3aGVuIHRoZSBlbmRwb2ludCBjYW4ndCBiZSBxdWVyaWVkIG9yIHJldHVybnMgbm8gdmVjdG9yIC0gdGhlXG4gKiBkaW1lbnNpb24gaXMgaW5mb3JtYXRpb25hbCwgbmV2ZXIgcmVxdWlyZWQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIHBpbmdFbWJlZGRpbmdEaW1lbnNpb24oXG4gIGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSxcbiAgbmFtZTogc3RyaW5nLFxuKTogUHJvbWlzZTxudW1iZXIgfCB1bmRlZmluZWQ+IHtcbiAgdHJ5IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGNsaWVudC5zZXJ2aW5nRW5kcG9pbnRzLnF1ZXJ5KHsgbmFtZSwgaW5wdXQ6IFwicGluZ1wiIH0pO1xuICAgIGNvbnN0IGRpbWVuc2lvbiA9IHJlc3BvbnNlLmRhdGE/LlswXT8uZW1iZWRkaW5nPy5sZW5ndGg7XG4gICAgaWYgKHR5cGVvZiBkaW1lbnNpb24gPT09IFwibnVtYmVyXCIgJiYgZGltZW5zaW9uID4gMCkgcmV0dXJuIGRpbWVuc2lvbjtcbiAgICBsb2dnZXIud2FybihcImVtYmVkZGluZyBwaW5nIHJldHVybmVkIG5vIHZlY3RvclwiLCB7IG5hbWUgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLndhcm4oXCJlbWJlZGRpbmcgcGluZyBmYWlsZWRcIiwgeyBuYW1lLCBlcnJvcjogZXJyb3IuZXJyb3JNZXNzYWdlKGVycikgfSk7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG4vKipcbiAqIFB1bGwgdGhlIEZvdW5kYXRpb24gTW9kZWwgQVBJIGBxdWFsaXR5YCAvIGBzcGVlZGAgLyBgY29zdGAgc2NvcmVzIG9mZiBhXG4gKiBzZXJ2aW5nLWVuZHBvaW50IGxpc3RpbmcgZW50cnkuIERhdGFicmlja3MgcmV0dXJucyB0aGVzZSB1bmRlclxuICogYGNvbmZpZy5zZXJ2ZWRfZW50aXRpZXNbXS5mb3VuZGF0aW9uX21vZGVsLmFpX2dhdGV3YXlfbW9kZWxfcHJvZmlsZWBcbiAqIChzbmFrZV9jYXNlIGF0IHRoZSB3aXJlIGxldmVsLCBwcmVzZXJ2ZWQgdmVyYmF0aW0gYnkgdGhlIFNESyksIGJ1dCB0aGUgZmllbGRcbiAqIGlzIG5ld2VyIHRoYW4gdGhlIHR5cGVkIGBGb3VuZGF0aW9uTW9kZWxgIGludGVyZmFjZSwgc28gd2UgcmVhZCBpdCB0aHJvdWdoIGFcbiAqIHN0cnVjdHVyYWwgY2FzdC4gUmV0dXJucyBgdW5kZWZpbmVkYCB3aGVuIG5vIHNlcnZlZCBlbnRpdHkgY2FycmllcyBhIHByb2ZpbGVcbiAqIChjdXN0b20gbW9kZWxzLCBlbWJlZGRpbmdzLCBhbmQgYnJhbmQtbmV3IGVuZHBvaW50cyB0aGF0IERhdGFicmlja3MgaGFzIG5vdFxuICogc2NvcmVkIHlldCkuXG4gKi9cbmZ1bmN0aW9uIGV4dHJhY3RQcm9maWxlKGVwOiB1bmtub3duKTogTW9kZWxQcm9maWxlIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZW50aXRpZXMgPSAoXG4gICAgZXAgYXMge1xuICAgICAgY29uZmlnPzoge1xuICAgICAgICBzZXJ2ZWRfZW50aXRpZXM/OiBBcnJheTx7XG4gICAgICAgICAgZm91bmRhdGlvbl9tb2RlbD86IHtcbiAgICAgICAgICAgIGFpX2dhdGV3YXlfbW9kZWxfcHJvZmlsZT86IHtcbiAgICAgICAgICAgICAgcXVhbGl0eT86IG51bWJlcjtcbiAgICAgICAgICAgICAgc3BlZWQ/OiBudW1iZXI7XG4gICAgICAgICAgICAgIGNvc3Q/OiBudW1iZXI7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH07XG4gICAgICAgIH0+O1xuICAgICAgfTtcbiAgICB9XG4gICkuY29uZmlnPy5zZXJ2ZWRfZW50aXRpZXM7XG4gIGlmICghZW50aXRpZXMpIHJldHVybiB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgZW50aXR5IG9mIGVudGl0aWVzKSB7XG4gICAgY29uc3QgcmF3ID0gZW50aXR5LmZvdW5kYXRpb25fbW9kZWw/LmFpX2dhdGV3YXlfbW9kZWxfcHJvZmlsZTtcbiAgICBpZiAoIXJhdykgY29udGludWU7XG4gICAgY29uc3QgcHJvZmlsZTogTW9kZWxQcm9maWxlID0ge307XG4gICAgaWYgKE51bWJlci5pc0Zpbml0ZShyYXcucXVhbGl0eSkpIHByb2ZpbGUucXVhbGl0eSA9IHJhdy5xdWFsaXR5O1xuICAgIGlmIChOdW1iZXIuaXNGaW5pdGUocmF3LnNwZWVkKSkgcHJvZmlsZS5zcGVlZCA9IHJhdy5zcGVlZDtcbiAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHJhdy5jb3N0KSkgcHJvZmlsZS5jb3N0ID0gcmF3LmNvc3Q7XG4gICAgaWYgKE9iamVjdC5rZXlzKHByb2ZpbGUpLmxlbmd0aCA+IDApIHJldHVybiBwcm9maWxlO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogRm9yY2UtZXZpY3QgY2FjaGVkIGVuZHBvaW50IGxpc3RpbmdzIHZpYSBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyYC4gV2l0aCBhXG4gKiBgaG9zdGAgZGVsZXRlcyB0aGF0IG9uZSB3b3Jrc3BhY2UncyBlbnRyeTsgd2l0aG91dCBvbmUgY2xlYXJzIGV2ZXJ5IGNhY2hlXG4gKiBlbnRyeSBvbiB0aGUgbWFuYWdlciAoc2luY2UgYENhY2hlTWFuYWdlcmAgZG9lc24ndCBleHBvc2UgYSBuYW1lc3BhY2Utc2NvcGVkXG4gKiBjbGVhciwgdGhpcyBpcyB0aGUgYnJ1dGUtZm9yY2UgcGF0aCAtIGZpbmUgZm9yIHRlc3RzLCBhdm9pZCBpbiBzdGVhZHktc3RhdGVcbiAqIGNvZGUpLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xlYXJTZXJ2aW5nRW5kcG9pbnRzQ2FjaGUoaG9zdD86IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBjYWNoZSA9IENhY2hlTWFuYWdlci5nZXRJbnN0YW5jZVN5bmMoKTtcbiAgaWYgKGhvc3QpIHtcbiAgICBjb25zdCBrZXkgPSBjYWNoZS5nZW5lcmF0ZUtleShbQ0FDSEVfS0VZX05BTUVTUEFDRSwgaG9zdF0sIFNIQVJFRF9VU0VSX0tFWSk7XG4gICAgYXdhaXQgY2FjaGUuZGVsZXRlKGtleSk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgY2FjaGUuY2xlYXIoKTtcbiAgfVxufVxuXG4vKipcbiAqIFJlc3VsdCBvZiBmdXp6eS1yZXNvbHZpbmcgYSB1c2VyLXN1cHBsaWVkIG1vZGVsIG5hbWUgYWdhaW5zdCB0aGUgbGl2ZVxuICogZW5kcG9pbnQgbGlzdC4gYHNjb3JlYCBpcyBGdXNlLmpzJ3MgZGlzdGFuY2UgKGAwYCBpcyBleGFjdCwgYDFgIGlzIG5vIG1hdGNoKTtcbiAqIGBtYXRjaGVkYCBpcyBgZmFsc2VgIHdoZW4gdGhlIHNjb3JlIGV4Y2VlZHMgdGhlIGNvbmZpZ3VyZWQgdGhyZXNob2xkIHNvXG4gKiBjYWxsZXJzIGNhbiBmYWxsIGJhY2sgdG8gdGhlIG9yaWdpbmFsIGlucHV0IChEYXRhYnJpY2tzIHdpbGwgdGhlbiByZXR1cm4gYVxuICogY2xlYW4gNDA0KS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXNvbHZlZE1vZGVsIHtcbiAgbW9kZWxJZDogc3RyaW5nO1xuICBtYXRjaGVkOiBib29sZWFuO1xuICBzY29yZT86IG51bWJlcjtcbn1cblxuLyoqIE9wdGlvbnMgYWNjZXB0ZWQgYnkge0BsaW5rIHJlc29sdmVNb2RlbElkfSAvIHtAbGluayBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZU1vZGVsT3B0aW9ucyB7XG4gIC8qKiBGdXNlLmpzIHRocmVzaG9sZCAoMCA9IGV4YWN0LCAxID0gYW55dGhpbmcpLiBEZWZhdWx0IGAwLjRgLiAqL1xuICB0aHJlc2hvbGQ/OiBudW1iZXI7XG4gIC8qKiBSZXF1aXJlIGEgbW9kZWwgdmVyaWZpZWQgZm9yIGEgY29tcGxldGUgZnVuY3Rpb24tdG9vbCByb3VuZC10cmlwLiAqL1xuICByZXF1aXJlc1Rvb2xzPzogYm9vbGVhbjtcbn1cblxuLyoqIEEgc2VydmluZyBlbmRwb2ludCBwYWlyZWQgd2l0aCBpdHMgZnV6enktbWF0Y2ggZGlzdGFuY2UgZm9yIGEgcXVlcnkuICovXG5leHBvcnQgaW50ZXJmYWNlIFNjb3JlZEVuZHBvaW50IHtcbiAgZW5kcG9pbnQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnk7XG4gIC8qKiBGdXNlLmpzIGRpc3RhbmNlOiBgMGAgaXMgZXhhY3QsIGAxYCBpcyBubyBtYXRjaC4gKi9cbiAgc2NvcmU6IG51bWJlcjtcbn1cblxuLyoqXG4gKiBGdXp6eS1yYW5rIGVuZHBvaW50cyBieSBob3cgY2xvc2VseSB0aGVpciBgbmFtZWAgbWF0Y2hlcyBgaW5wdXRgLCBiZXN0XG4gKiAobG93ZXN0IHNjb3JlKSBmaXJzdCwga2VlcGluZyBvbmx5IHRob3NlIHdpdGhpbiBgdGhyZXNob2xkYDpcbiAqXG4gKiAxLiBBbiBleGFjdCBuYW1lIG1hdGNoIHNob3J0LWNpcmN1aXRzIHRvIGEgc2luZ2xlIGBzY29yZTogMGAgcmVzdWx0LlxuICogMi4gT3RoZXJ3aXNlIHRoZSBpbnB1dCBpcyB0b2tlbml6ZWQgKGRhc2hlcyAvIHVuZGVyc2NvcmVzIC8gc3BhY2VzIGJlY29tZVxuICogICAgc2VwYXJhdG9ycykgYW5kIGZlZCB0aHJvdWdoIEZ1c2UuanMgZXh0ZW5kZWQgc2VhcmNoLCB3aGljaCBBTkQtcyBlYWNoXG4gKiAgICB0b2tlbiB3aXRoIGZ1enp5IG1hdGNoaW5nIGVuYWJsZWQgLSB0aGUgXCJ0b2tlbml6ZWQgZnV6enkgbWF0Y2hcIiBhIGNhbGxlclxuICogICAgcmVhY2hlcyBmb3Igd2hlbiB0aGV5IHR5cGUgYFwiY2xhdWRlIHNvbm5ldFwiYCBpbnN0ZWFkIG9mIHRoZSBmdWxsIGVuZHBvaW50XG4gKiAgICBuYW1lLlxuICpcbiAqIFJldHVybnMgYFtdYCBmb3IgYW4gZW1wdHkgZW5kcG9pbnQgbGlzdCBvciB3aGVuIGBpbnB1dGAgdG9rZW5pemVzIHRvIG5vdGhpbmcsXG4gKiBzbyBjYWxsZXJzIGZhbGwgYmFjayB0byB0aGUgcmF3IGlucHV0IGFuZCBsZXQgRGF0YWJyaWNrcyBzdXJmYWNlIGEgY2xlYW4gNDA0LlxuICogVGhpcyBtdWx0aS1yZXN1bHQgY29yZSBpcyBzaGFyZWQgYnkge0BsaW5rIHJlc29sdmVNb2RlbElkfSAoc2luZ2xlIGJlc3QpIGFuZFxuICogdGhlIHJhbmtlZCBgbG9va3VwTW9kZWxzYCBzZWxlY3Rvci5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlYXJjaFNlcnZpbmdFbmRwb2ludHMoXG4gIGlucHV0OiBzdHJpbmcsXG4gIGVuZHBvaW50czogcmVhZG9ubHkgU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuICBvcHRpb25zOiBSZXNvbHZlTW9kZWxPcHRpb25zID0ge30sXG4pOiBTY29yZWRFbmRwb2ludFtdIHtcbiAgaWYgKGVuZHBvaW50cy5sZW5ndGggPT09IDApIHJldHVybiBbXTtcbiAgZm9yIChjb25zdCBlcCBvZiBlbmRwb2ludHMpIHtcbiAgICBpZiAoZXAubmFtZSA9PT0gaW5wdXQpIHJldHVybiBbeyBlbmRwb2ludDogZXAsIHNjb3JlOiAwIH1dO1xuICB9XG4gIGNvbnN0IHRocmVzaG9sZCA9IG9wdGlvbnMudGhyZXNob2xkID8/IERFRkFVTFRfRlVaWllfVEhSRVNIT0xEO1xuICAvLyBGdXNlIDcuMyBoYXMgbm8gYnVpbHQtaW4gdG9rZW5pemUgaG9vazsgaW4gZXh0ZW5kZWQgc2VhcmNoLCBzcGFjZS1zZXBhcmF0ZWRcbiAgLy8gdG9rZW5zIGFyZSBBTkQtZWQgd2l0aCBmdXp6eSBtYXRjaGluZyBlbmFibGVkLiBXZSBsZWFuIG9uIHRoZSBzaGFyZWRcbiAgLy8gdG9rZW5pemVyIHNvIHRoZSBzcGxpdHRpbmcgcnVsZXMgc3RheSBjb25zaXN0ZW50IHdpdGggdGhlIHJlc3Qgb2YgdGhlIHRvb2xraXQuXG4gIGNvbnN0IHF1ZXJ5ID0gQXJyYXkuZnJvbShcbiAgICBzdHJpbmcudG9rZW5pemVXaXRoT3B0aW9ucyh7IGxvd2VyQ2FzZTogdHJ1ZSwgY2FtZWxDYXNlOiBmYWxzZSB9LCBpbnB1dCksXG4gICkuam9pbihcIiBcIik7XG4gIGlmICghcXVlcnkpIHJldHVybiBbXTtcbiAgY29uc3QgZnVzZSA9IG5ldyBGdXNlKGVuZHBvaW50cywge1xuICAgIGtleXM6IFtcIm5hbWVcIl0sXG4gICAgdGhyZXNob2xkLFxuICAgIGlnbm9yZUxvY2F0aW9uOiB0cnVlLFxuICAgIGluY2x1ZGVTY29yZTogdHJ1ZSxcbiAgICB1c2VFeHRlbmRlZFNlYXJjaDogdHJ1ZSxcbiAgICBpc0Nhc2VTZW5zaXRpdmU6IGZhbHNlLFxuICB9KTtcbiAgcmV0dXJuIGZ1c2VcbiAgICAuc2VhcmNoKHF1ZXJ5KVxuICAgIC5maWx0ZXIoKHIpID0+IChyLnNjb3JlID8/IDApIDw9IHRocmVzaG9sZClcbiAgICAubWFwKChyKSA9PiAoeyBlbmRwb2ludDogci5pdGVtLCBzY29yZTogci5zY29yZSA/PyAwIH0pKTtcbn1cblxuLyoqXG4gKiBTbmFwIGEgdXNlci1zdXBwbGllZCBtb2RlbCBuYW1lIHRvIHRoZSBzaW5nbGUgY2xvc2VzdCBjb25maWd1cmVkIHNlcnZpbmdcbiAqIGVuZHBvaW50IHZpYSB7QGxpbmsgc2VhcmNoU2VydmluZ0VuZHBvaW50c30uIFJldHVybnMgdGhlIGlucHV0IHVuY2hhbmdlZCB3aXRoXG4gKiBgbWF0Y2hlZDogZmFsc2VgIHdoZW4gbm90aGluZyBzY29yZXMgd2l0aGluIHRoZSB0aHJlc2hvbGQgKG9yIHRoZSBjYXRhbG9ndWVcbiAqIGlzIGVtcHR5KSwgc28gYSBkZWxpYmVyYXRlIG1vZGVsIGlkIGlzIG5ldmVyIHNpbGVudGx5IHJld3JpdHRlbiB0byBhXG4gKiBzaW1pbGFyLWxvb2tpbmcgbmVpZ2hib3VyIGFuZCB0aGUgdXBzdHJlYW0gY2FsbCBzdXJmYWNlcyB0aGUgY2Fub25pY2FsIDQwNC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVNb2RlbElkKFxuICBpbnB1dDogc3RyaW5nLFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgb3B0aW9uczogUmVzb2x2ZU1vZGVsT3B0aW9ucyA9IHt9LFxuKTogUmVzb2x2ZWRNb2RlbCB7XG4gIGNvbnN0IFtiZXN0XSA9IHNlYXJjaFNlcnZpbmdFbmRwb2ludHMoaW5wdXQsIGVuZHBvaW50cywgb3B0aW9ucyk7XG4gIGlmIChiZXN0KSB7XG4gICAgcmV0dXJuIHsgbW9kZWxJZDogYmVzdC5lbmRwb2ludC5uYW1lLCBtYXRjaGVkOiB0cnVlLCBzY29yZTogYmVzdC5zY29yZSB9O1xuICB9XG4gIHJldHVybiB7IG1vZGVsSWQ6IGlucHV0LCBtYXRjaGVkOiBmYWxzZSB9O1xufVxuIl19
|
|
292
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmluZy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9zZXJ2aW5nLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFbEQsT0FBTyxFQUFFLEtBQUssRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQsT0FBTyxFQUNMLFFBQVEsRUFDUixPQUFPLEVBQ1AsS0FBSyxHQUdOLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxJQUFJLE1BQU0sU0FBUyxDQUFDO0FBRTNCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUNqRCxPQUFPLEVBQUUsV0FBVyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBRWpFLE1BQU0sRUFBRSxVQUFVLEVBQUUsR0FBRyxLQUFLLENBQUM7QUFFN0IsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztBQVMzQywwR0FBMEc7QUFDMUcsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUcsQ0FBQyxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFeEQsNkVBQTZFO0FBQzdFLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLEdBQUcsQ0FBQztBQUUzQyxnRUFBZ0U7QUFDaEUsTUFBTSxtQkFBbUIsR0FBRyxtQkFBbUIsQ0FBQztBQUVoRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDO0FBV3ZDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxvQkFBb0IsQ0FDeEMsTUFBMkIsRUFDM0IsSUFBWSxFQUNaLFVBQXVDLEVBQUU7SUFFekMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksMEJBQTBCLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzdGLE9BQU8sWUFBWSxDQUFDLGVBQWUsRUFBRSxDQUFDLFlBQVksQ0FDaEQsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsRUFDM0IsR0FBRyxFQUFFLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxFQUM1QixlQUFlLEVBQ2YsRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLENBQ2hCLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSw0QkFBNEIsQ0FDaEQsTUFBMkI7SUFFM0IsTUFBTSxHQUFHLEdBQTZCLEVBQUUsQ0FBQztJQUN6QyxJQUFJLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUN0RCxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUk7WUFBRSxTQUFTO1FBQ3ZCLE1BQU0sT0FBTyxHQUFHLGNBQWMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sZ0JBQWdCLEdBQUcscUJBQXFCLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hELEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFDUCxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUk7WUFDYixvRUFBb0U7WUFDcEUscUVBQXFFO1lBQ3JFLFdBQVcsRUFBRSxPQUFPLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxtQkFBbUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN6RSxHQUFHLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzNDLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDbkQsR0FBRyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQzNFLEdBQUcsQ0FBQyxFQUFFLENBQUMsV0FBVyxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7WUFDeEUsYUFBYSxFQUFFLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ3RELEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMvQixHQUFHLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7U0FDN0QsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLG1CQUFtQixDQUFDLEVBRzVCO0lBQ0MsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLENBQ3ZCLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLGNBQWMsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLGFBQWEsSUFBSSxDQUFDLENBQUMsR0FBRyxLQUFLLE1BQU0sQ0FDL0UsQ0FBQztJQUNGLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO0lBQzlDLElBQUksT0FBTztRQUFFLE9BQU8sT0FBTyxDQUFDO0lBQzVCLEtBQUssTUFBTSxNQUFNLElBQUksRUFBRSxDQUFDLE1BQU0sRUFBRSxlQUFlLElBQUksRUFBRSxFQUFFLENBQUM7UUFDdEQsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hFLElBQUksUUFBUTtZQUFFLE9BQU8sUUFBUSxDQUFDO0lBQ2hDLENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCxLQUFLLFVBQVUsY0FBYyxDQUFDLE1BQTJCO0lBQ3ZELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUM3QixNQUFNLEdBQUcsR0FBRyxNQUFNLDRCQUE0QixDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3ZELGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCLE1BQU0sMEJBQTBCLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQzlDLE1BQU0sQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBQ2pGLE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxTQUFtQztJQUM1RCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDdEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQTRCLENBQUM7SUFDcEQsS0FBSyxNQUFNLEdBQUcsSUFBSSxpQkFBaUIsRUFBRSxDQUFDO1FBQ3BDLEtBQUssTUFBTSxFQUFFLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztJQUMzRCxDQUFDO0lBQ0QsS0FBSyxNQUFNLE9BQU8sSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUNoQyxNQUFNLEdBQUcsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxJQUFJLEdBQUcsS0FBSyxTQUFTO1lBQUUsT0FBTyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7SUFDN0MsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsS0FBSyxVQUFVLDBCQUEwQixDQUN2QyxNQUEyQixFQUMzQixTQUFtQztJQUVuQyxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQ2YsU0FBUztTQUNOLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxVQUFVLENBQUMsU0FBUyxDQUFDO1NBQy9DLEdBQUcsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7UUFDckIsTUFBTSxTQUFTLEdBQUcsTUFBTSxzQkFBc0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JFLElBQUksU0FBUyxLQUFLLFNBQVM7WUFBRSxPQUFPLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztJQUM3RCxDQUFDLENBQUMsQ0FDTCxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsS0FBSyxVQUFVLHNCQUFzQixDQUNuQyxNQUEyQixFQUMzQixJQUFZO0lBRVosSUFBSSxDQUFDO1FBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsZ0JBQWdCLENBQUMsS0FBSyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzlFLE1BQU0sU0FBUyxHQUFHLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsTUFBTSxDQUFDO1FBQ3hELElBQUksT0FBTyxTQUFTLEtBQUssUUFBUSxJQUFJLFNBQVMsR0FBRyxDQUFDO1lBQUUsT0FBTyxTQUFTLENBQUM7UUFDckUsTUFBTSxDQUFDLElBQUksQ0FBQyxtQ0FBbUMsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDM0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsSUFBSSxDQUFDLHVCQUF1QixFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMvRSxPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILFNBQVMsY0FBYyxDQUFDLEVBQVc7SUFDakMsTUFBTSxRQUFRLEdBQ1osRUFhRCxDQUFDLE1BQU0sRUFBRSxlQUFlLENBQUM7SUFDMUIsSUFBSSxDQUFDLFFBQVE7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUNoQyxLQUFLLE1BQU0sTUFBTSxJQUFJLFFBQVEsRUFBRSxDQUFDO1FBQzlCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSx3QkFBd0IsQ0FBQztRQUM5RCxJQUFJLENBQUMsR0FBRztZQUFFLFNBQVM7UUFDbkIsTUFBTSxPQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUNqQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQztZQUFFLE9BQU8sQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQztRQUNoRSxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQztZQUFFLE9BQU8sQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQztRQUMxRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQztZQUFFLE9BQU8sQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQztRQUN2RCxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUM7WUFBRSxPQUFPLE9BQU8sQ0FBQztJQUN0RCxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsMEJBQTBCLENBQUMsSUFBYTtJQUM1RCxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDN0MsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUNULE1BQU0sR0FBRyxHQUFHLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxtQkFBbUIsRUFBRSxJQUFJLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUM1RSxNQUFNLEtBQUssQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUIsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUN0QixDQUFDO0FBQ0gsQ0FBQztBQThCRDs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxNQUFNLFVBQVUsc0JBQXNCLENBQ3BDLEtBQWEsRUFDYixTQUE0QyxFQUM1QyxVQUErQixFQUFFO0lBRWpDLElBQUksU0FBUyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDdEMsS0FBSyxNQUFNLEVBQUUsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUMzQixJQUFJLEVBQUUsQ0FBQyxJQUFJLEtBQUssS0FBSztZQUFFLE9BQU8sQ0FBQyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUNELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksdUJBQXVCLENBQUM7SUFDL0QsOEVBQThFO0lBQzlFLHVFQUF1RTtJQUN2RSxpRkFBaUY7SUFDakYsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FDdEIsTUFBTSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQ3pFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ1osSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUN0QixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUU7UUFDL0IsSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO1FBQ2QsU0FBUztRQUNULGNBQWMsRUFBRSxJQUFJO1FBQ3BCLFlBQVksRUFBRSxJQUFJO1FBQ2xCLGlCQUFpQixFQUFFLElBQUk7UUFDdkIsZUFBZSxFQUFFLEtBQUs7S0FDdkIsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxJQUFJO1NBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQztTQUNiLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQyxJQUFJLFNBQVMsQ0FBQztTQUMxQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDN0QsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxjQUFjLENBQzVCLEtBQWEsRUFDYixTQUE0QyxFQUM1QyxVQUErQixFQUFFO0lBRWpDLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQ2pFLElBQUksSUFBSSxFQUFFLENBQUM7UUFDVCxPQUFPLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUMzRSxDQUFDO0lBQ0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxDQUFDO0FBQzVDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIExpdmUgRGF0YWJyaWNrcyBNb2RlbCBTZXJ2aW5nIGNhdGFsb2d1ZSBhY2Nlc3MuXG4gKlxuICogTGlzdHMgdGhlIHdvcmtzcGFjZSdzIGAvc2VydmluZy1lbmRwb2ludHNgIG9uY2UgcGVyIGhvc3QgYW5kIGNhY2hlcyB0aGVcbiAqIHJlc3VsdCB3aXRoIGEgVFRMIHZpYSBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyYCwgd2l0aCBjb25jdXJyZW50IGNhbGxlcnNcbiAqIHNoYXJpbmcgb25lIGluLWZsaWdodCBwcm9taXNlICh0aGUgY29hbGVzY2luZyBwYXR0ZXJuIG9mIFB5dGhvbidzXG4gKiBgY2FjaGV0b29scy1hc3luY2ApLiBTdXJmYWNlcyBlYWNoIGVuZHBvaW50IGFzIGEgc3RhYmxlXG4gKiB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeX0gLSBpbmNsdWRpbmcgdGhlIEZvdW5kYXRpb24gTW9kZWwgQVBJXG4gKiBgcXVhbGl0eWAgLyBgc3BlZWRgIC8gYGNvc3RgIHByb2ZpbGUgd2hlbiBwcmVzZW50LCB0aGUgY2xhc3NpZmllZFxuICoge0BsaW5rIE1vZGVsQ2xhc3N9LCBhbmQgKGZvciBlbWJlZGRpbmcgZW5kcG9pbnRzKSB0aGUgbWVhc3VyZWQgdmVjdG9yXG4gKiBgZGltZW5zaW9uYCAtIGFuZCBzbmFwcyBsb29zZSwgaHVtYW4tdHlwZWQgbmFtZXMgdG8gcmVhbCBlbmRwb2ludCBpZHNcbiAqIHRocm91Z2ggYGZ1c2UuanNgIGV4dGVuZGVkIHNlYXJjaCBzbyB0b2tlbnMgbGlrZSBgXCJjbGF1ZGUgc29ubmV0XCJgIHJlc29sdmUgdG9cbiAqIGBkYXRhYnJpY2tzLWNsYXVkZS1zb25uZXQtNC02YC5cbiAqXG4gKiBUaGUgY2xhc3Mgc3RhbXAgYW5kIGVtYmVkZGluZyBkaW1lbnNpb24gYXJlIGNvbXB1dGVkIG9uY2UgcGVyIGNhY2hlIGxvYWQ6XG4gKiBldmVyeSBlbWJlZGRpbmcgZW5kcG9pbnQgaXMgXCJwaW5nZWRcIiBpbiBwYXJhbGxlbCBhbmQgdGhlIHJlc3VsdGluZyB2ZWN0b3JcbiAqIGxlbmd0aCByZWNvcmRlZCwgc28gdGhlIGNvc3QgaXMgcGFpZCBvbiBhIGNhY2hlIG1pc3MsIG5vdCBwZXIgcmVhZC4gVGhlIHBpbmdcbiAqIGlzIGJlc3QtZWZmb3J0IC0gYSBmYWlsdXJlIGxvZ3MgYXQgZGVidWcgYW5kIGxlYXZlcyBgZGltZW5zaW9uYCB1bnNldCByYXRoZXJcbiAqIHRoYW4gZmFpbGluZyB0aGUgd2hvbGUgbGlzdGluZy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgQ2FjaGVNYW5hZ2VyIH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgYXBwa2l0IH0gZnJvbSBcIkBkYngtdG9vbHMvYXBwa2l0XCI7XG5pbXBvcnQgeyBlcnJvciwgbG9nLCBzdHJpbmcgfSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtY29yZVwiO1xuaW1wb3J0IHtcbiAgY2xhc3NpZnksXG4gIGRpc3BsYXksXG4gIG1vZGVsLFxuICB0eXBlIE1vZGVsUHJvZmlsZSxcbiAgdHlwZSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5LFxufSBmcm9tIFwiQGRieC10b29scy9zaGFyZWQtbW9kZWxcIjtcbmltcG9ydCBGdXNlIGZyb20gXCJmdXNlLmpzXCI7XG5cbmltcG9ydCB7IE1PREVMX0NMQVNTX09SREVSIH0gZnJvbSBcIi4vY2xhc3Nlcy50c1wiO1xuaW1wb3J0IHsgbW9kZWxGYW1pbHksIG1vZGVsUmVhc29uaW5nRWZmb3J0cyB9IGZyb20gXCIuL3BvbGljeS50c1wiO1xuXG5jb25zdCB7IE1vZGVsQ2xhc3MgfSA9IG1vZGVsO1xuXG5jb25zdCBsb2dnZXIgPSBsb2cubG9nZ2VyKFwibW9kZWwvc2VydmluZ1wiKTtcblxuLyoqXG4gKiBTdHJ1Y3R1cmFsIHR5cGUgZm9yIHRoZSBEYXRhYnJpY2tzIHdvcmtzcGFjZSBjbGllbnQsIHJlLWV4cG9ydGVkIHNvIHRoZSByZXN0XG4gKiBvZiB0aGlzIHBhY2thZ2UgY2FuIGtlZXAgaW1wb3J0aW5nIGl0IGZyb20gaGVyZS4gU2VlXG4gKiBgYXBwa2l0LldvcmtzcGFjZUNsaWVudExpa2VgIChub2RlLWFwcGtpdCkgZm9yIHRoZSBjYW5vbmljYWwgZGVmaW5pdGlvbi5cbiAqL1xuZXhwb3J0IHR5cGUgV29ya3NwYWNlQ2xpZW50TGlrZSA9IFBpY2s8YXBwa2l0LldvcmtzcGFjZUNsaWVudExpa2UsIFwic2VydmluZ0VuZHBvaW50c1wiPjtcblxuLyoqIERlZmF1bHQgVFRMIGZvciB0aGUgaW4tbWVtb3J5IGVuZHBvaW50IGNhY2hlLiBNYXRjaGVzIHRoZSBEYXRhYnJpY2tzIFNESydzIHNlc3Npb24gbGlmZXRpbWUgYnVkZ2V0LiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTU9ERUxfQ0FDSEVfVFRMX01TID0gNSAqIDYwICogMTAwMDtcblxuLyoqIERlZmF1bHQgRnVzZS5qcyBzY29yZSB0aHJlc2hvbGQgYmVsb3cgd2hpY2ggYSBmdXp6eSBtYXRjaCBpcyBhY2NlcHRlZC4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0ZVWlpZX1RIUkVTSE9MRCA9IDAuNDtcblxuLyoqIENhY2hlIGtleSBwYXJ0cyB1bmRlciB3aGljaCBlbmRwb2ludCBsaXN0aW5ncyBhcmUgc3RvcmVkLiAqL1xuY29uc3QgQ0FDSEVfS0VZX05BTUVTUEFDRSA9IFwic2VydmluZy1lbmRwb2ludHNcIjtcblxuLyoqXG4gKiBTdGFibGUgYHVzZXJLZXlgIGFyZyBmb3IgQXBwS2l0J3MgYENhY2hlTWFuYWdlci5nZXRPckV4ZWN1dGVgLiBFbmRwb2ludFxuICogdmlzaWJpbGl0eSBpcyBlZmZlY3RpdmVseSB3b3Jrc3BhY2Utc2NvcGVkICh3ZSBjYWNoZSBieSBob3N0IGluIHRoZSBrZXlcbiAqIHBhcnRzKSwgc28gYSBzaW5nbGUgc2hhcmVkIGtleSBsZXRzIGV2ZXJ5IHVzZXIgb2YgdGhlIHNhbWUgd29ya3NwYWNlIHNoYXJlXG4gKiBvbmUgY2FjaGVkIGZldGNoIGFuZCBjb2FsZXNjZSBvbiB0aGUgaW4tZmxpZ2h0IHByb21pc2UuIFBlcm1pc3Npb25zIGNhblxuICogZGlmZmVyIGluIHRoZW9yeSwgYnV0IHRoZSBGb3VuZGF0aW9uIE1vZGVsIEFQSSBjYXRhbG9ndWUgaXMgdGhlIHNhbWUgdmlldyBmb3JcbiAqIGV2ZXJ5IGNhbGxlci5cbiAqL1xuY29uc3QgU0hBUkVEX1VTRVJfS0VZID0gXCJtb2RlbC1zaGFyZWRcIjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBsaXN0U2VydmluZ0VuZHBvaW50c30uICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RTZXJ2aW5nRW5kcG9pbnRzT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBPdmVycmlkZSB0aGUgZGVmYXVsdCBjYWNoZSBUVEwgZm9yIHRoaXMgY2FsbCwgaW4gbWlsbGlzZWNvbmRzLiBGb3J3YXJkZWQgdG9cbiAgICogYENhY2hlTWFuYWdlcmAgYXMgc2Vjb25kcy5cbiAgICovXG4gIHR0bE1zPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIExpc3QgTW9kZWwgU2VydmluZyBlbmRwb2ludHMgZm9yIHRoZSB3b3Jrc3BhY2Ugb3duaW5nIGBjbGllbnRgLCByb3V0ZWRcbiAqIHRocm91Z2ggQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAuIFRoZSBtYW5hZ2VyIGdpdmVzIHVzIGV2ZXJ5dGhpbmdcbiAqIGBjYWNoZXRvb2xzLlRUTENhY2hlYCBwcm92aWRlcyBwbHVzIHdoYXQgYGNhY2hldG9vbHMtYXN5bmNgIGFkZHMgb24gdG9wOlxuICogcGVyLWVudHJ5IFRUTCwgaW4tZmxpZ2h0IHJlcXVlc3QgY29hbGVzY2luZyAoY29uY3VycmVudCBjYWxsZXJzIHNoYXJlIG9uZVxuICogZmV0Y2ggdmlhIHRoZSBtYW5hZ2VyJ3MgaW50ZXJuYWwgYGluRmxpZ2h0UmVxdWVzdHNgIG1hcCksIGJvdW5kZWQgc2l6ZSxcbiAqIHRlbGVtZXRyeSBzcGFucyAoYGNhY2hlLmdldE9yRXhlY3V0ZWApLCBhbmQgb3B0aW9uYWwgTGFrZWJhc2UgcGVyc2lzdGVuY2Ugc29cbiAqIHRoZSBjYXRhbG9ndWUgc3Vydml2ZXMgcmVzdGFydHMgd2hlbiB0aGUgbGFrZWJhc2UgcGx1Z2luIGlzIHdpcmVkIHVwLlxuICpcbiAqIFJldHVybnMgcGxhaW4ge0BsaW5rIFNlcnZpbmdFbmRwb2ludFN1bW1hcnl9IG9iamVjdHMgKGEgc3RhYmxlIHN1YnNldCBvZiB0aGVcbiAqIFNESyB0eXBlKSBzbyBjYWNoZSBoaXRzIG5ldmVyIGV4cG9zZSBzdGFsZSBTREsgaW50ZXJuYWxzLiBFcnJvcnMgZnJvbVxuICogYENhY2hlTWFuYWdlcmAgb3IgdGhlIFNESyBmZXRjaCBwcm9wYWdhdGUgdG8gdGhlIGNhbGxlciAtIHdlIGRvbid0IHN3YWxsb3dcbiAqIHRoZW0gc28gdXNlcnMgc2VlIHRoZSByZWFsIGF1dGggLyBuZXR3b3JrIGlzc3VlLlxuICpcbiAqIEBwYXJhbSBob3N0IC0gV29ya3NwYWNlIGhvc3QgdXNlZCBhcyB0aGUgY2FjaGUga2V5LiBQYXNzIHRoZSB2YWx1ZSByZXNvbHZlZFxuICogICBmcm9tIGBjbGllbnQuY29uZmlnLmdldEhvc3QoKWAgc28gbXVsdGktaG9zdCBhcHBzIHNoYXJlIG9uZSBlbnRyeSBwZXJcbiAqICAgd29ya3NwYWNlLlxuICogQHBhcmFtIG9wdGlvbnMudHRsTXMgLSBPdmVycmlkZSB0aGUgZGVmYXVsdCBUVEwganVzdCBmb3IgdGhpcyBjYWxsLiBGb3J3YXJkZWRcbiAqICAgdG8gYENhY2hlTWFuYWdlcmAgYXMgc2Vjb25kcy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RTZXJ2aW5nRW5kcG9pbnRzKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIGhvc3Q6IHN0cmluZyxcbiAgb3B0aW9uczogTGlzdFNlcnZpbmdFbmRwb2ludHNPcHRpb25zID0ge30sXG4pOiBQcm9taXNlPFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXT4ge1xuICBjb25zdCB0dGxTZWMgPSBNYXRoLm1heCgxLCBNYXRoLnJvdW5kKChvcHRpb25zLnR0bE1zID8/IERFRkFVTFRfTU9ERUxfQ0FDSEVfVFRMX01TKSAvIDEwMDApKTtcbiAgcmV0dXJuIENhY2hlTWFuYWdlci5nZXRJbnN0YW5jZVN5bmMoKS5nZXRPckV4ZWN1dGUoXG4gICAgW0NBQ0hFX0tFWV9OQU1FU1BBQ0UsIGhvc3RdLFxuICAgICgpID0+IGZldGNoRW5kcG9pbnRzKGNsaWVudCksXG4gICAgU0hBUkVEX1VTRVJfS0VZLFxuICAgIHsgdHRsOiB0dGxTZWMgfSxcbiAgKTtcbn1cblxuLyoqXG4gKiBMaXN0IHRoZSB3b3Jrc3BhY2UncyBzZXJ2aW5nIGVuZHBvaW50cyBhcyBtaW5pbWFsXG4gKiB7QGxpbmsgU2VydmluZ0VuZHBvaW50U3VtbWFyeX0gb2JqZWN0cyBzdHJhaWdodCBmcm9tIHRoZSBTREs6IG5vIGNhY2hpbmcsIGFuZFxuICogbm9uZSBvZiB0aGUgY2FjaGUtbG9hZCBlbnJpY2htZW50ICh7QGxpbmsgbGlzdFNlcnZpbmdFbmRwb2ludHN9IGFkZHMgdGhlXG4gKiB7QGxpbmsgTW9kZWxDbGFzc30gc3RhbXAgYW5kIHRoZSBlbWJlZGRpbmctZGltZW5zaW9uIHByb2JlKS4gVXNlIHRoaXMgZm9yIGFcbiAqIG9uZS1zaG90LCBkZXBlbmRlbmN5LWxpZ2h0IGxpc3RpbmcgLSBlLmcuIGEgQ0xJIHRoYXQgb25seSBuZWVkcyBuYW1lcy90YXNrc1xuICogZm9yIGZ1enp5IHJlc29sdXRpb24gYW5kIGRvZXNuJ3Qgd2FudCBBcHBLaXQncyBgQ2FjaGVNYW5hZ2VyYCBvciB0aGVcbiAqIHBlci1lbWJlZGRpbmcgcGluZyBjb3N0LiBQcmVmZXIge0BsaW5rIGxpc3RTZXJ2aW5nRW5kcG9pbnRzfSBmb3IgdGhlIGNhY2hlZCxcbiAqIGVucmljaGVkIHZpZXcuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBsaXN0U2VydmluZ0VuZHBvaW50c1VuY2FjaGVkKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4pOiBQcm9taXNlPFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXT4ge1xuICBjb25zdCBvdXQ6IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSA9IFtdO1xuICBmb3IgYXdhaXQgKGNvbnN0IGVwIG9mIGNsaWVudC5zZXJ2aW5nRW5kcG9pbnRzLmxpc3QoKSkge1xuICAgIGlmICghZXAubmFtZSkgY29udGludWU7XG4gICAgY29uc3QgcHJvZmlsZSA9IGV4dHJhY3RQcm9maWxlKGVwKTtcbiAgICBjb25zdCBmYW1pbHkgPSBtb2RlbEZhbWlseShlcC5uYW1lKTtcbiAgICBjb25zdCByZWFzb25pbmdFZmZvcnRzID0gbW9kZWxSZWFzb25pbmdFZmZvcnRzKGVwLm5hbWUpO1xuICAgIG91dC5wdXNoKHtcbiAgICAgIG5hbWU6IGVwLm5hbWUsXG4gICAgICAvLyBQcmVmZXIgYSBEYXRhYnJpY2tzLXByb3ZpZGVkIGh1bWFuIG5hbWUgKGEgZGlzcGxheS1uYW1lIHRhZyBvciBhblxuICAgICAgLy8gZXh0ZXJuYWwtbW9kZWwgbmFtZSk7IGVsc2UgZGVyaXZlIGEgdGl0bGUtY2FzZWQgbGFiZWwgZnJvbSB0aGUgaWQuXG4gICAgICBkaXNwbGF5TmFtZTogZGlzcGxheS50b01vZGVsRGlzcGxheU5hbWUoZXAubmFtZSwgcHJvdmlkZWREaXNwbGF5TmFtZShlcCkpLFxuICAgICAgLi4uKGZhbWlseSAhPT0gdW5kZWZpbmVkID8geyBmYW1pbHkgfSA6IHt9KSxcbiAgICAgIC4uLihlcC50YXNrICE9PSB1bmRlZmluZWQgPyB7IHRhc2s6IGVwLnRhc2sgfSA6IHt9KSxcbiAgICAgIC4uLihlcC5zdGF0ZT8ucmVhZHkgIT09IHVuZGVmaW5lZCA/IHsgc3RhdGU6IFN0cmluZyhlcC5zdGF0ZS5yZWFkeSkgfSA6IHt9KSxcbiAgICAgIC4uLihlcC5kZXNjcmlwdGlvbiAhPT0gdW5kZWZpbmVkID8geyBkZXNjcmlwdGlvbjogZXAuZGVzY3JpcHRpb24gfSA6IHt9KSxcbiAgICAgIHN1cHBvcnRzVG9vbHM6IGNsYXNzaWZ5LnN1cHBvcnRzVG9vbHNCeUZhbWlseShlcC5uYW1lKSxcbiAgICAgIC4uLihwcm9maWxlID8geyBwcm9maWxlIH0gOiB7fSksXG4gICAgICAuLi4ocmVhc29uaW5nRWZmb3J0cy5sZW5ndGggPiAwID8geyByZWFzb25pbmdFZmZvcnRzIH0gOiB7fSksXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIG91dDtcbn1cblxuLyoqXG4gKiBQdWxsIGEgRGF0YWJyaWNrcy1wcm92aWRlZCBodW1hbiBuYW1lIG9mZiBhIHNlcnZpbmcgZW5kcG9pbnQsIGlmIGFueTpcbiAqIGEgYGRpc3BsYXlfbmFtZWAgLyBgZGlzcGxheU5hbWVgIC8gYG5hbWVgIHRhZyBmaXJzdCwgdGhlbiBhblxuICogZXh0ZXJuYWwtbW9kZWwgYG5hbWVgIGZyb20gdGhlIHNlcnZlZC1lbnRpdHkgY29uZmlnLiBSZXR1cm5zIGBudWxsYFxuICogd2hlbiB0aGUgZW5kcG9pbnQgY2FycmllcyBubyBleHBsaWNpdCBuYW1lICh0aGUgY29tbW9uIGNhc2UgZm9yXG4gKiBGb3VuZGF0aW9uIE1vZGVsIEFQSSBlbmRwb2ludHMpLCBzbyB0aGUgY2FsbGVyIGZhbGxzIGJhY2sgdG8gZGVyaXZpbmdcbiAqIG9uZSBmcm9tIHRoZSBpZC5cbiAqL1xuZnVuY3Rpb24gcHJvdmlkZWREaXNwbGF5TmFtZShlcDoge1xuICB0YWdzPzogQXJyYXk8eyBrZXk6IHN0cmluZzsgdmFsdWU/OiBzdHJpbmcgfT47XG4gIGNvbmZpZz86IHsgc2VydmVkX2VudGl0aWVzPzogQXJyYXk8eyBleHRlcm5hbF9tb2RlbD86IHsgbmFtZT86IHN0cmluZyB9IH0+IH07XG59KTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHRhZyA9IGVwLnRhZ3M/LmZpbmQoXG4gICAgKHQpID0+IHQua2V5ID09PSBcImRpc3BsYXlfbmFtZVwiIHx8IHQua2V5ID09PSBcImRpc3BsYXlOYW1lXCIgfHwgdC5rZXkgPT09IFwibmFtZVwiLFxuICApO1xuICBjb25zdCBmcm9tVGFnID0gc3RyaW5nLnRyaW1Ub051bGwodGFnPy52YWx1ZSk7XG4gIGlmIChmcm9tVGFnKSByZXR1cm4gZnJvbVRhZztcbiAgZm9yIChjb25zdCBlbnRpdHkgb2YgZXAuY29uZmlnPy5zZXJ2ZWRfZW50aXRpZXMgPz8gW10pIHtcbiAgICBjb25zdCBleHRlcm5hbCA9IHN0cmluZy50cmltVG9OdWxsKGVudGl0eS5leHRlcm5hbF9tb2RlbD8ubmFtZSk7XG4gICAgaWYgKGV4dGVybmFsKSByZXR1cm4gZXh0ZXJuYWw7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGZldGNoRW5kcG9pbnRzKGNsaWVudDogV29ya3NwYWNlQ2xpZW50TGlrZSk6IFByb21pc2U8U2VydmluZ0VuZHBvaW50U3VtbWFyeVtdPiB7XG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gIGNvbnN0IG91dCA9IGF3YWl0IGxpc3RTZXJ2aW5nRW5kcG9pbnRzVW5jYWNoZWQoY2xpZW50KTtcbiAgc3RhbXBNb2RlbENsYXNzZXMob3V0KTtcbiAgYXdhaXQgbWVhc3VyZUVtYmVkZGluZ0RpbWVuc2lvbnMoY2xpZW50LCBvdXQpO1xuICBsb2dnZXIuZGVidWcoXCJsaXN0ZWRcIiwgeyBjb3VudDogb3V0Lmxlbmd0aCwgZWxhcHNlZE1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0IH0pO1xuICByZXR1cm4gb3V0O1xufVxuXG4vKipcbiAqIFN0YW1wIGVhY2ggc3VtbWFyeSdzIHtAbGluayBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5LmNsYXNzfSBmcm9tIHRoZSByZWxhdGl2ZVxuICogY2xhc3NpZmljYXRpb24gb2YgdGhlIHdob2xlIHNldC4gTXV0YXRlcyBgc3VtbWFyaWVzYCBpbiBwbGFjZS4gRW5kcG9pbnRzIHRoZVxuICogY2xhc3NpZmllciBkb2Vzbid0IHJlY29nbml6ZSAoY3VzdG9tLCB1bnNjb3JlZCwgbm9uLUxMTSkgYXJlIGxlZnQgd2l0aG91dCBhXG4gKiBjbGFzcy5cbiAqL1xuZnVuY3Rpb24gc3RhbXBNb2RlbENsYXNzZXMoc3VtbWFyaWVzOiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10pOiB2b2lkIHtcbiAgY29uc3QgYnVja2V0cyA9IGNsYXNzaWZ5LmNsYXNzaWZ5RW5kcG9pbnRzKHN1bW1hcmllcyk7XG4gIGNvbnN0IGNsYXNzT2YgPSBuZXcgTWFwPHN0cmluZywgbW9kZWwuTW9kZWxDbGFzcz4oKTtcbiAgZm9yIChjb25zdCBjbHMgb2YgTU9ERUxfQ0xBU1NfT1JERVIpIHtcbiAgICBmb3IgKGNvbnN0IGVwIG9mIGJ1Y2tldHNbY2xzXSkgY2xhc3NPZi5zZXQoZXAubmFtZSwgY2xzKTtcbiAgfVxuICBmb3IgKGNvbnN0IHN1bW1hcnkgb2Ygc3VtbWFyaWVzKSB7XG4gICAgY29uc3QgY2xzID0gY2xhc3NPZi5nZXQoc3VtbWFyeS5uYW1lKTtcbiAgICBpZiAoY2xzICE9PSB1bmRlZmluZWQpIHN1bW1hcnkuY2xhc3MgPSBjbHM7XG4gIH1cbn1cblxuLyoqXG4gKiBNZWFzdXJlIHRoZSBlbWJlZGRpbmcgdmVjdG9yIGRpbWVuc2lvbiBvZiBldmVyeSB7QGxpbmsgTW9kZWxDbGFzcy5FbWJlZGRpbmd9XG4gKiBlbmRwb2ludCBieSBwaW5naW5nIGl0IG9uY2UsIGFsbCBpbiBwYXJhbGxlbC4gTXV0YXRlcyB0aGUgbWF0Y2hpbmcgc3VtbWFyaWVzXG4gKiBpbiBwbGFjZSB3aXRoIHRoZSByZXN1bHRpbmcgYGRpbWVuc2lvbmAuIFJ1bnMgb25seSBvbiBhIGNhY2hlIG1pc3MgKGl0J3NcbiAqIGNhbGxlZCBmcm9tIHtAbGluayBmZXRjaEVuZHBvaW50c30pLCBzbyB0aGUgcHJvYmUgY29zdCBpcyBhbW9ydGl6ZWQgYWNyb3NzIHRoZVxuICogY2FjaGVkIFRUTCB3aW5kb3cuIFBlci1lbmRwb2ludCBmYWlsdXJlcyBhcmUgc3dhbGxvd2VkIChsb2dnZWQgYXQgd2Fybikgc29cbiAqIG9uZSB1bnJlYWNoYWJsZSBlbWJlZGRpbmcgbW9kZWwgbmV2ZXIgZmFpbHMgdGhlIGxpc3RpbmcuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIG1lYXN1cmVFbWJlZGRpbmdEaW1lbnNpb25zKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIHN1bW1hcmllczogU2VydmluZ0VuZHBvaW50U3VtbWFyeVtdLFxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGF3YWl0IFByb21pc2UuYWxsKFxuICAgIHN1bW1hcmllc1xuICAgICAgLmZpbHRlcigocykgPT4gcy5jbGFzcyA9PT0gTW9kZWxDbGFzcy5FbWJlZGRpbmcpXG4gICAgICAubWFwKGFzeW5jIChzdW1tYXJ5KSA9PiB7XG4gICAgICAgIGNvbnN0IGRpbWVuc2lvbiA9IGF3YWl0IHBpbmdFbWJlZGRpbmdEaW1lbnNpb24oY2xpZW50LCBzdW1tYXJ5Lm5hbWUpO1xuICAgICAgICBpZiAoZGltZW5zaW9uICE9PSB1bmRlZmluZWQpIHN1bW1hcnkuZGltZW5zaW9uID0gZGltZW5zaW9uO1xuICAgICAgfSksXG4gICk7XG59XG5cbi8qKlxuICogQmVzdC1lZmZvcnQgZW1iZWRkaW5nIGRpbWVuc2lvbiBwcm9iZTogcXVlcnkgYG5hbWVgIHdpdGggYSB0aW55IGBcInBpbmdcImBcbiAqIGlucHV0IGFuZCByZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgcmV0dXJuZWQgdmVjdG9yLiBSZXR1cm5zIGB1bmRlZmluZWRgIChhbmRcbiAqIGxvZ3MgYXQgd2Fybikgd2hlbiB0aGUgZW5kcG9pbnQgY2FuJ3QgYmUgcXVlcmllZCBvciByZXR1cm5zIG5vIHZlY3RvciAtIHRoZVxuICogZGltZW5zaW9uIGlzIGluZm9ybWF0aW9uYWwsIG5ldmVyIHJlcXVpcmVkLlxuICovXG5hc3luYyBmdW5jdGlvbiBwaW5nRW1iZWRkaW5nRGltZW5zaW9uKFxuICBjbGllbnQ6IFdvcmtzcGFjZUNsaWVudExpa2UsXG4gIG5hbWU6IHN0cmluZyxcbik6IFByb21pc2U8bnVtYmVyIHwgdW5kZWZpbmVkPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBjbGllbnQuc2VydmluZ0VuZHBvaW50cy5xdWVyeSh7IG5hbWUsIGlucHV0OiBcInBpbmdcIiB9KTtcbiAgICBjb25zdCBkaW1lbnNpb24gPSByZXNwb25zZS5kYXRhPy5bMF0/LmVtYmVkZGluZz8ubGVuZ3RoO1xuICAgIGlmICh0eXBlb2YgZGltZW5zaW9uID09PSBcIm51bWJlclwiICYmIGRpbWVuc2lvbiA+IDApIHJldHVybiBkaW1lbnNpb247XG4gICAgbG9nZ2VyLndhcm4oXCJlbWJlZGRpbmcgcGluZyByZXR1cm5lZCBubyB2ZWN0b3JcIiwgeyBuYW1lIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci53YXJuKFwiZW1iZWRkaW5nIHBpbmcgZmFpbGVkXCIsIHsgbmFtZSwgZXJyb3I6IGVycm9yLmVycm9yTWVzc2FnZShlcnIpIH0pO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cblxuLyoqXG4gKiBQdWxsIHRoZSBGb3VuZGF0aW9uIE1vZGVsIEFQSSBgcXVhbGl0eWAgLyBgc3BlZWRgIC8gYGNvc3RgIHNjb3JlcyBvZmYgYVxuICogc2VydmluZy1lbmRwb2ludCBsaXN0aW5nIGVudHJ5LiBEYXRhYnJpY2tzIHJldHVybnMgdGhlc2UgdW5kZXJcbiAqIGBjb25maWcuc2VydmVkX2VudGl0aWVzW10uZm91bmRhdGlvbl9tb2RlbC5haV9nYXRld2F5X21vZGVsX3Byb2ZpbGVgXG4gKiAoc25ha2VfY2FzZSBhdCB0aGUgd2lyZSBsZXZlbCwgcHJlc2VydmVkIHZlcmJhdGltIGJ5IHRoZSBTREspLCBidXQgdGhlIGZpZWxkXG4gKiBpcyBuZXdlciB0aGFuIHRoZSB0eXBlZCBgRm91bmRhdGlvbk1vZGVsYCBpbnRlcmZhY2UsIHNvIHdlIHJlYWQgaXQgdGhyb3VnaCBhXG4gKiBzdHJ1Y3R1cmFsIGNhc3QuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiBubyBzZXJ2ZWQgZW50aXR5IGNhcnJpZXMgYSBwcm9maWxlXG4gKiAoY3VzdG9tIG1vZGVscywgZW1iZWRkaW5ncywgYW5kIGJyYW5kLW5ldyBlbmRwb2ludHMgdGhhdCBEYXRhYnJpY2tzIGhhcyBub3RcbiAqIHNjb3JlZCB5ZXQpLlxuICovXG5mdW5jdGlvbiBleHRyYWN0UHJvZmlsZShlcDogdW5rbm93bik6IE1vZGVsUHJvZmlsZSB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGVudGl0aWVzID0gKFxuICAgIGVwIGFzIHtcbiAgICAgIGNvbmZpZz86IHtcbiAgICAgICAgc2VydmVkX2VudGl0aWVzPzogQXJyYXk8e1xuICAgICAgICAgIGZvdW5kYXRpb25fbW9kZWw/OiB7XG4gICAgICAgICAgICBhaV9nYXRld2F5X21vZGVsX3Byb2ZpbGU/OiB7XG4gICAgICAgICAgICAgIHF1YWxpdHk/OiBudW1iZXI7XG4gICAgICAgICAgICAgIHNwZWVkPzogbnVtYmVyO1xuICAgICAgICAgICAgICBjb3N0PzogbnVtYmVyO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9O1xuICAgICAgICB9PjtcbiAgICAgIH07XG4gICAgfVxuICApLmNvbmZpZz8uc2VydmVkX2VudGl0aWVzO1xuICBpZiAoIWVudGl0aWVzKSByZXR1cm4gdW5kZWZpbmVkO1xuICBmb3IgKGNvbnN0IGVudGl0eSBvZiBlbnRpdGllcykge1xuICAgIGNvbnN0IHJhdyA9IGVudGl0eS5mb3VuZGF0aW9uX21vZGVsPy5haV9nYXRld2F5X21vZGVsX3Byb2ZpbGU7XG4gICAgaWYgKCFyYXcpIGNvbnRpbnVlO1xuICAgIGNvbnN0IHByb2ZpbGU6IE1vZGVsUHJvZmlsZSA9IHt9O1xuICAgIGlmIChOdW1iZXIuaXNGaW5pdGUocmF3LnF1YWxpdHkpKSBwcm9maWxlLnF1YWxpdHkgPSByYXcucXVhbGl0eTtcbiAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHJhdy5zcGVlZCkpIHByb2ZpbGUuc3BlZWQgPSByYXcuc3BlZWQ7XG4gICAgaWYgKE51bWJlci5pc0Zpbml0ZShyYXcuY29zdCkpIHByb2ZpbGUuY29zdCA9IHJhdy5jb3N0O1xuICAgIGlmIChPYmplY3Qua2V5cyhwcm9maWxlKS5sZW5ndGggPiAwKSByZXR1cm4gcHJvZmlsZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIEZvcmNlLWV2aWN0IGNhY2hlZCBlbmRwb2ludCBsaXN0aW5ncyB2aWEgQXBwS2l0J3MgYENhY2hlTWFuYWdlcmAuIFdpdGggYVxuICogYGhvc3RgIGRlbGV0ZXMgdGhhdCBvbmUgd29ya3NwYWNlJ3MgZW50cnk7IHdpdGhvdXQgb25lIGNsZWFycyBldmVyeSBjYWNoZVxuICogZW50cnkgb24gdGhlIG1hbmFnZXIgKHNpbmNlIGBDYWNoZU1hbmFnZXJgIGRvZXNuJ3QgZXhwb3NlIGEgbmFtZXNwYWNlLXNjb3BlZFxuICogY2xlYXIsIHRoaXMgaXMgdGhlIGJydXRlLWZvcmNlIHBhdGggLSBmaW5lIGZvciB0ZXN0cywgYXZvaWQgaW4gc3RlYWR5LXN0YXRlXG4gKiBjb2RlKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsZWFyU2VydmluZ0VuZHBvaW50c0NhY2hlKGhvc3Q/OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgY2FjaGUgPSBDYWNoZU1hbmFnZXIuZ2V0SW5zdGFuY2VTeW5jKCk7XG4gIGlmIChob3N0KSB7XG4gICAgY29uc3Qga2V5ID0gY2FjaGUuZ2VuZXJhdGVLZXkoW0NBQ0hFX0tFWV9OQU1FU1BBQ0UsIGhvc3RdLCBTSEFSRURfVVNFUl9LRVkpO1xuICAgIGF3YWl0IGNhY2hlLmRlbGV0ZShrZXkpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IGNhY2hlLmNsZWFyKCk7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXN1bHQgb2YgZnV6enktcmVzb2x2aW5nIGEgdXNlci1zdXBwbGllZCBtb2RlbCBuYW1lIGFnYWluc3QgdGhlIGxpdmVcbiAqIGVuZHBvaW50IGxpc3QuIGBzY29yZWAgaXMgRnVzZS5qcydzIGRpc3RhbmNlIChgMGAgaXMgZXhhY3QsIGAxYCBpcyBubyBtYXRjaCk7XG4gKiBgbWF0Y2hlZGAgaXMgYGZhbHNlYCB3aGVuIHRoZSBzY29yZSBleGNlZWRzIHRoZSBjb25maWd1cmVkIHRocmVzaG9sZCBzb1xuICogY2FsbGVycyBjYW4gZmFsbCBiYWNrIHRvIHRoZSBvcmlnaW5hbCBpbnB1dCAoRGF0YWJyaWNrcyB3aWxsIHRoZW4gcmV0dXJuIGFcbiAqIGNsZWFuIDQwNCkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmVzb2x2ZWRNb2RlbCB7XG4gIG1vZGVsSWQ6IHN0cmluZztcbiAgbWF0Y2hlZDogYm9vbGVhbjtcbiAgc2NvcmU/OiBudW1iZXI7XG59XG5cbi8qKiBPcHRpb25zIGFjY2VwdGVkIGJ5IHtAbGluayByZXNvbHZlTW9kZWxJZH0gLyB7QGxpbmsgc2VhcmNoU2VydmluZ0VuZHBvaW50c30uICovXG5leHBvcnQgaW50ZXJmYWNlIFJlc29sdmVNb2RlbE9wdGlvbnMge1xuICAvKiogRnVzZS5qcyB0aHJlc2hvbGQgKDAgPSBleGFjdCwgMSA9IGFueXRoaW5nKS4gRGVmYXVsdCBgMC40YC4gKi9cbiAgdGhyZXNob2xkPzogbnVtYmVyO1xuICAvKiogUmVxdWlyZSBhIG1vZGVsIHZlcmlmaWVkIGZvciBhIGNvbXBsZXRlIGZ1bmN0aW9uLXRvb2wgcm91bmQtdHJpcC4gKi9cbiAgcmVxdWlyZXNUb29scz86IGJvb2xlYW47XG59XG5cbi8qKiBBIHNlcnZpbmcgZW5kcG9pbnQgcGFpcmVkIHdpdGggaXRzIGZ1enp5LW1hdGNoIGRpc3RhbmNlIGZvciBhIHF1ZXJ5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBTY29yZWRFbmRwb2ludCB7XG4gIGVuZHBvaW50OiBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5O1xuICAvKiogRnVzZS5qcyBkaXN0YW5jZTogYDBgIGlzIGV4YWN0LCBgMWAgaXMgbm8gbWF0Y2guICovXG4gIHNjb3JlOiBudW1iZXI7XG59XG5cbi8qKlxuICogRnV6enktcmFuayBlbmRwb2ludHMgYnkgaG93IGNsb3NlbHkgdGhlaXIgYG5hbWVgIG1hdGNoZXMgYGlucHV0YCwgYmVzdFxuICogKGxvd2VzdCBzY29yZSkgZmlyc3QsIGtlZXBpbmcgb25seSB0aG9zZSB3aXRoaW4gYHRocmVzaG9sZGA6XG4gKlxuICogMS4gQW4gZXhhY3QgbmFtZSBtYXRjaCBzaG9ydC1jaXJjdWl0cyB0byBhIHNpbmdsZSBgc2NvcmU6IDBgIHJlc3VsdC5cbiAqIDIuIE90aGVyd2lzZSB0aGUgaW5wdXQgaXMgdG9rZW5pemVkIChkYXNoZXMgLyB1bmRlcnNjb3JlcyAvIHNwYWNlcyBiZWNvbWVcbiAqICAgIHNlcGFyYXRvcnMpIGFuZCBmZWQgdGhyb3VnaCBGdXNlLmpzIGV4dGVuZGVkIHNlYXJjaCwgd2hpY2ggQU5ELXMgZWFjaFxuICogICAgdG9rZW4gd2l0aCBmdXp6eSBtYXRjaGluZyBlbmFibGVkIC0gdGhlIFwidG9rZW5pemVkIGZ1enp5IG1hdGNoXCIgYSBjYWxsZXJcbiAqICAgIHJlYWNoZXMgZm9yIHdoZW4gdGhleSB0eXBlIGBcImNsYXVkZSBzb25uZXRcImAgaW5zdGVhZCBvZiB0aGUgZnVsbCBlbmRwb2ludFxuICogICAgbmFtZS5cbiAqXG4gKiBSZXR1cm5zIGBbXWAgZm9yIGFuIGVtcHR5IGVuZHBvaW50IGxpc3Qgb3Igd2hlbiBgaW5wdXRgIHRva2VuaXplcyB0byBub3RoaW5nLFxuICogc28gY2FsbGVycyBmYWxsIGJhY2sgdG8gdGhlIHJhdyBpbnB1dCBhbmQgbGV0IERhdGFicmlja3Mgc3VyZmFjZSBhIGNsZWFuIDQwNC5cbiAqIFRoaXMgbXVsdGktcmVzdWx0IGNvcmUgaXMgc2hhcmVkIGJ5IHtAbGluayByZXNvbHZlTW9kZWxJZH0gKHNpbmdsZSBiZXN0KSBhbmRcbiAqIHRoZSByYW5rZWQgYGxvb2t1cE1vZGVsc2Agc2VsZWN0b3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzKFxuICBpbnB1dDogc3RyaW5nLFxuICBlbmRwb2ludHM6IHJlYWRvbmx5IFNlcnZpbmdFbmRwb2ludFN1bW1hcnlbXSxcbiAgb3B0aW9uczogUmVzb2x2ZU1vZGVsT3B0aW9ucyA9IHt9LFxuKTogU2NvcmVkRW5kcG9pbnRbXSB7XG4gIGlmIChlbmRwb2ludHMubGVuZ3RoID09PSAwKSByZXR1cm4gW107XG4gIGZvciAoY29uc3QgZXAgb2YgZW5kcG9pbnRzKSB7XG4gICAgaWYgKGVwLm5hbWUgPT09IGlucHV0KSByZXR1cm4gW3sgZW5kcG9pbnQ6IGVwLCBzY29yZTogMCB9XTtcbiAgfVxuICBjb25zdCB0aHJlc2hvbGQgPSBvcHRpb25zLnRocmVzaG9sZCA/PyBERUZBVUxUX0ZVWlpZX1RIUkVTSE9MRDtcbiAgLy8gRnVzZSA3LjMgaGFzIG5vIGJ1aWx0LWluIHRva2VuaXplIGhvb2s7IGluIGV4dGVuZGVkIHNlYXJjaCwgc3BhY2Utc2VwYXJhdGVkXG4gIC8vIHRva2VucyBhcmUgQU5ELWVkIHdpdGggZnV6enkgbWF0Y2hpbmcgZW5hYmxlZC4gV2UgbGVhbiBvbiB0aGUgc2hhcmVkXG4gIC8vIHRva2VuaXplciBzbyB0aGUgc3BsaXR0aW5nIHJ1bGVzIHN0YXkgY29uc2lzdGVudCB3aXRoIHRoZSByZXN0IG9mIHRoZSB0b29sa2l0LlxuICBjb25zdCBxdWVyeSA9IEFycmF5LmZyb20oXG4gICAgc3RyaW5nLnRva2VuaXplV2l0aE9wdGlvbnMoeyBsb3dlckNhc2U6IHRydWUsIGNhbWVsQ2FzZTogZmFsc2UgfSwgaW5wdXQpLFxuICApLmpvaW4oXCIgXCIpO1xuICBpZiAoIXF1ZXJ5KSByZXR1cm4gW107XG4gIGNvbnN0IGZ1c2UgPSBuZXcgRnVzZShlbmRwb2ludHMsIHtcbiAgICBrZXlzOiBbXCJuYW1lXCJdLFxuICAgIHRocmVzaG9sZCxcbiAgICBpZ25vcmVMb2NhdGlvbjogdHJ1ZSxcbiAgICBpbmNsdWRlU2NvcmU6IHRydWUsXG4gICAgdXNlRXh0ZW5kZWRTZWFyY2g6IHRydWUsXG4gICAgaXNDYXNlU2Vuc2l0aXZlOiBmYWxzZSxcbiAgfSk7XG4gIHJldHVybiBmdXNlXG4gICAgLnNlYXJjaChxdWVyeSlcbiAgICAuZmlsdGVyKChyKSA9PiAoci5zY29yZSA/PyAwKSA8PSB0aHJlc2hvbGQpXG4gICAgLm1hcCgocikgPT4gKHsgZW5kcG9pbnQ6IHIuaXRlbSwgc2NvcmU6IHIuc2NvcmUgPz8gMCB9KSk7XG59XG5cbi8qKlxuICogU25hcCBhIHVzZXItc3VwcGxpZWQgbW9kZWwgbmFtZSB0byB0aGUgc2luZ2xlIGNsb3Nlc3QgY29uZmlndXJlZCBzZXJ2aW5nXG4gKiBlbmRwb2ludCB2aWEge0BsaW5rIHNlYXJjaFNlcnZpbmdFbmRwb2ludHN9LiBSZXR1cm5zIHRoZSBpbnB1dCB1bmNoYW5nZWQgd2l0aFxuICogYG1hdGNoZWQ6IGZhbHNlYCB3aGVuIG5vdGhpbmcgc2NvcmVzIHdpdGhpbiB0aGUgdGhyZXNob2xkIChvciB0aGUgY2F0YWxvZ3VlXG4gKiBpcyBlbXB0eSksIHNvIGEgZGVsaWJlcmF0ZSBtb2RlbCBpZCBpcyBuZXZlciBzaWxlbnRseSByZXdyaXR0ZW4gdG8gYVxuICogc2ltaWxhci1sb29raW5nIG5laWdoYm91ciBhbmQgdGhlIHVwc3RyZWFtIGNhbGwgc3VyZmFjZXMgdGhlIGNhbm9uaWNhbCA0MDQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlTW9kZWxJZChcbiAgaW5wdXQ6IHN0cmluZyxcbiAgZW5kcG9pbnRzOiByZWFkb25seSBTZXJ2aW5nRW5kcG9pbnRTdW1tYXJ5W10sXG4gIG9wdGlvbnM6IFJlc29sdmVNb2RlbE9wdGlvbnMgPSB7fSxcbik6IFJlc29sdmVkTW9kZWwge1xuICBjb25zdCBbYmVzdF0gPSBzZWFyY2hTZXJ2aW5nRW5kcG9pbnRzKGlucHV0LCBlbmRwb2ludHMsIG9wdGlvbnMpO1xuICBpZiAoYmVzdCkge1xuICAgIHJldHVybiB7IG1vZGVsSWQ6IGJlc3QuZW5kcG9pbnQubmFtZSwgbWF0Y2hlZDogdHJ1ZSwgc2NvcmU6IGJlc3Quc2NvcmUgfTtcbiAgfVxuICByZXR1cm4geyBtb2RlbElkOiBpbnB1dCwgbWF0Y2hlZDogZmFsc2UgfTtcbn1cbiJdfQ==
|
package/lib/tsconfig.tsbuildinfo
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"root":["../src/classes.ts","../src/fallback.ts","../src/invoke.ts","../src/resolve.ts","../src/serving.ts","../index.ts"],"version":"5.9.3"}
|
|
1
|
+
{"root":["../src/classes.ts","../src/fallback.ts","../src/invoke.ts","../src/policy.ts","../src/resolve.ts","../src/serving.ts","../index.ts"],"version":"5.9.3"}
|
package/package.json
CHANGED
|
@@ -25,10 +25,10 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@databricks/appkit": "^0.60.0",
|
|
28
|
-
"@dbx-tools/appkit": "0.6.
|
|
29
|
-
"@dbx-tools/model-rs": "0.6.
|
|
30
|
-
"@dbx-tools/shared-core": "0.6.
|
|
31
|
-
"@dbx-tools/shared-model": "0.6.
|
|
28
|
+
"@dbx-tools/appkit": "0.6.225",
|
|
29
|
+
"@dbx-tools/model-rs": "0.6.225",
|
|
30
|
+
"@dbx-tools/shared-core": "0.6.225",
|
|
31
|
+
"@dbx-tools/shared-model": "0.6.225",
|
|
32
32
|
"fuse.js": "^7.4.2"
|
|
33
33
|
},
|
|
34
34
|
"main": "./lib/index.js",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"./package.json": "./package.json"
|
|
46
46
|
}
|
|
47
47
|
},
|
|
48
|
-
"version": "0.6.
|
|
48
|
+
"version": "0.6.225",
|
|
49
49
|
"types": "./lib/index.d.ts",
|
|
50
50
|
"type": "module",
|
|
51
51
|
"exports": {
|
package/src/policy.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser-safe model metadata projected from the Rust policy bindings.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
modelFamily as modelFamilyWithRust,
|
|
9
|
+
reasoningEffortNamesByFamily,
|
|
10
|
+
} from "@dbx-tools/model-rs";
|
|
11
|
+
import type { ReasoningEffort } from "@dbx-tools/shared-model";
|
|
12
|
+
|
|
13
|
+
/** Return the normalized family parsed by the Rust model-name policy. */
|
|
14
|
+
export function modelFamily(name: string): string | undefined {
|
|
15
|
+
return modelFamilyWithRust(name);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Return the reasoning efforts accepted by a model family. */
|
|
19
|
+
export function modelReasoningEfforts(name: string): ReasoningEffort[] {
|
|
20
|
+
return reasoningEffortNamesByFamily(name);
|
|
21
|
+
}
|
package/src/resolve.ts
CHANGED
|
@@ -21,6 +21,12 @@
|
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
import { object } from "@dbx-tools/shared-core";
|
|
24
|
+
import {
|
|
25
|
+
ModelClass as ModelRsModelClass,
|
|
26
|
+
rankModels as rankModelsWithRust,
|
|
27
|
+
type ModelQuery as ModelRsModelQuery,
|
|
28
|
+
type ServingEndpointSummary as ModelRsServingEndpointSummary,
|
|
29
|
+
} from "@dbx-tools/model-rs";
|
|
24
30
|
import {
|
|
25
31
|
classify,
|
|
26
32
|
model,
|
|
@@ -29,7 +35,6 @@ import {
|
|
|
29
35
|
type ServingEndpointSummary,
|
|
30
36
|
} from "@dbx-tools/shared-model";
|
|
31
37
|
|
|
32
|
-
import { CHAT_CLASS_ORDER, classesAtOrBelow, MODEL_CLASS_ORDER } from "./classes.ts";
|
|
33
38
|
import { FALLBACK_MODEL_IDS, modelsForClass } from "./fallback.ts";
|
|
34
39
|
import {
|
|
35
40
|
listServingEndpoints,
|
|
@@ -41,15 +46,15 @@ import {
|
|
|
41
46
|
|
|
42
47
|
type ModelClass = model.ModelClass;
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
/** Preferred live family for an unconfigured general-purpose chat default. */
|
|
50
|
+
const DEFAULT_MODEL_FAMILY_SEARCH = "gpt";
|
|
51
|
+
|
|
52
|
+
const MODEL_CLASS_TO_RS: Readonly<Record<ModelClass, ModelRsModelClass>> = {
|
|
53
|
+
[model.ModelClass.ChatThinking]: ModelRsModelClass.ChatThinking,
|
|
54
|
+
[model.ModelClass.ChatBalanced]: ModelRsModelClass.ChatBalanced,
|
|
55
|
+
[model.ModelClass.ChatFast]: ModelRsModelClass.ChatFast,
|
|
56
|
+
[model.ModelClass.Embedding]: ModelRsModelClass.Embedding,
|
|
57
|
+
};
|
|
53
58
|
|
|
54
59
|
/** Caller intent passed to {@link resolveModel}. */
|
|
55
60
|
export interface ResolveModelInput {
|
|
@@ -82,6 +87,12 @@ export interface ResolveModelInput {
|
|
|
82
87
|
* the auto-classified catalogue.
|
|
83
88
|
*/
|
|
84
89
|
fallbacks?: readonly string[];
|
|
90
|
+
/**
|
|
91
|
+
* Refuse the static offline floor when the live catalogue has no match.
|
|
92
|
+
* Use for unpinned defaults that must always name a currently available
|
|
93
|
+
* endpoint.
|
|
94
|
+
*/
|
|
95
|
+
liveOnly?: boolean;
|
|
85
96
|
}
|
|
86
97
|
|
|
87
98
|
/** Outcome of {@link resolveModel}: the chosen id plus how it was reached. */
|
|
@@ -102,100 +113,76 @@ export interface SearchModelsInput extends ModelQuery {
|
|
|
102
113
|
ttlMs?: number;
|
|
103
114
|
}
|
|
104
115
|
|
|
105
|
-
/**
|
|
106
|
-
* Round a Fuse score to the display precision so version siblings that match a
|
|
107
|
-
* token identically (e.g. `opus-4-7` vs `opus-4-8` for the query `"opus"`) tie
|
|
108
|
-
* on match and let the class / within-class rank decide - which is what
|
|
109
|
-
* surfaces the newer, higher-quality sibling.
|
|
110
|
-
*/
|
|
111
|
-
function matchBucket(score: number | undefined): number {
|
|
112
|
-
return Math.round((score ?? 0) * 1000);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function modelVariantRank(name: string): number {
|
|
116
|
-
if (!/(?:^|[-_.])gpt(?:[-_.]|$)/i.test(name)) return 2;
|
|
117
|
-
if (/(?:^|[-_.])sol(?:[-_.]|$)/i.test(name)) return 0;
|
|
118
|
-
if (/(?:^|[-_.])luna(?:[-_.]|$)/i.test(name)) return 1;
|
|
119
|
-
return 2;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
116
|
/**
|
|
123
117
|
* Rank the live catalogue against a {@link ModelQuery}, best-first.
|
|
124
118
|
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* {@link classify.classifyEndpoints}. Ranking is **match then class**:
|
|
130
|
-
*
|
|
131
|
-
* 1. With a `search`, only endpoints matching it survive, ordered by match
|
|
132
|
-
* distance (bucketed via {@link matchBucket} so near-identical scores tie),
|
|
133
|
-
* then by version, preferred model variant, class (more capable first), and
|
|
134
|
-
* the stable within-class rank.
|
|
135
|
-
* 2. Without a `search`, the class-then-rank candidate order stands.
|
|
136
|
-
*
|
|
137
|
-
* A `limit` truncates the result. Returns `[]` when nothing is eligible or
|
|
138
|
-
* matches - callers layer their own fallback.
|
|
119
|
+
* Rust owns classification, fuzzy scoring, family-version ordering, preferred
|
|
120
|
+
* variants, class ceilings, tool filtering, and result limiting. Node retains
|
|
121
|
+
* the caller's endpoint objects so fields outside the ranking contract remain
|
|
122
|
+
* available unchanged.
|
|
139
123
|
*/
|
|
140
124
|
export function lookupModels(
|
|
141
125
|
endpoints: readonly ServingEndpointSummary[],
|
|
142
126
|
query: ModelQuery = {},
|
|
143
127
|
): RankedModel[] {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
|
|
128
|
+
const endpointsByName = new Map(endpoints.map((endpoint) => [endpoint.name, endpoint]));
|
|
129
|
+
return rankModelsWithRust(endpoints.map(toModelRsEndpoint), toModelRsQuery(query)).map(
|
|
130
|
+
(ranked) => {
|
|
131
|
+
const endpoint = endpointsByName.get(ranked.endpoint.name);
|
|
132
|
+
if (!endpoint) {
|
|
133
|
+
throw new Error(`Rust model ranking returned unknown endpoint "${ranked.endpoint.name}"`);
|
|
134
|
+
}
|
|
135
|
+
return {
|
|
136
|
+
endpoint,
|
|
137
|
+
modelClass: fromModelRsClass(ranked.modelClass),
|
|
138
|
+
...(ranked.score !== undefined ? { score: ranked.score } : {}),
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
);
|
|
142
|
+
}
|
|
147
143
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
144
|
+
/** Convert a public model query to the generated Rust ranking contract. */
|
|
145
|
+
function toModelRsQuery(query: ModelQuery): ModelRsModelQuery {
|
|
146
|
+
return {
|
|
147
|
+
search: query.search,
|
|
148
|
+
modelClass: query.modelClass === undefined ? undefined : MODEL_CLASS_TO_RS[query.modelClass],
|
|
149
|
+
requiresTools: query.requiresTools ?? false,
|
|
150
|
+
includeDeprecated: false,
|
|
151
|
+
limit: query.limit,
|
|
152
|
+
threshold: query.threshold,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
157
155
|
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
.filter(
|
|
176
|
-
(c) => !gptFamilySearch || !/(?:^|[-_.])gpt[-_.]?oss(?:[-_.]|$)/i.test(c.endpoint.name),
|
|
177
|
-
)
|
|
178
|
-
.map((c) => ({ ...c, score: scores.get(c.endpoint.name) }))
|
|
179
|
-
.sort((a, b) => {
|
|
180
|
-
const byMatch = matchBucket(a.score) - matchBucket(b.score);
|
|
181
|
-
if (byMatch !== 0) return byMatch;
|
|
182
|
-
if (versionedFamilySearch) {
|
|
183
|
-
const aVersion = classify.versionTuple(a.endpoint.name);
|
|
184
|
-
const bVersion = classify.versionTuple(b.endpoint.name);
|
|
185
|
-
for (let index = 0; index < 3; index++) {
|
|
186
|
-
const byVersion = (bVersion[index] ?? 0) - (aVersion[index] ?? 0);
|
|
187
|
-
if (byVersion !== 0) return byVersion;
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
const byVariant = modelVariantRank(a.endpoint.name) - modelVariantRank(b.endpoint.name);
|
|
191
|
-
if (byVariant !== 0) return byVariant;
|
|
192
|
-
return MODEL_CLASS_ORDER.indexOf(a.modelClass) - MODEL_CLASS_ORDER.indexOf(b.modelClass);
|
|
193
|
-
});
|
|
194
|
-
} else {
|
|
195
|
-
ranked = candidates;
|
|
196
|
-
}
|
|
156
|
+
/** Convert a discovered endpoint to the generated Rust ranking contract. */
|
|
157
|
+
function toModelRsEndpoint(endpoint: ServingEndpointSummary): ModelRsServingEndpointSummary {
|
|
158
|
+
return {
|
|
159
|
+
name: endpoint.name,
|
|
160
|
+
displayName: endpoint.displayName,
|
|
161
|
+
task: endpoint.task,
|
|
162
|
+
state: endpoint.state,
|
|
163
|
+
description: endpoint.description,
|
|
164
|
+
supportsTools: endpoint.supportsTools,
|
|
165
|
+
profile: endpoint.profile,
|
|
166
|
+
modelClass: endpoint.class === undefined ? undefined : MODEL_CLASS_TO_RS[endpoint.class],
|
|
167
|
+
serviceNames: new Map(Object.entries(endpoint.serviceNames ?? {})),
|
|
168
|
+
modelServiceName: endpoint.modelServiceName,
|
|
169
|
+
reasoningEfforts: [],
|
|
170
|
+
status: { deprecated: endpoint.status?.deprecated ?? false },
|
|
171
|
+
};
|
|
172
|
+
}
|
|
197
173
|
|
|
198
|
-
|
|
174
|
+
/** Convert a generated Rust class to the browser-safe public enum. */
|
|
175
|
+
function fromModelRsClass(modelClass: ModelRsModelClass): ModelClass {
|
|
176
|
+
switch (modelClass) {
|
|
177
|
+
case ModelRsModelClass.ChatThinking:
|
|
178
|
+
return model.ModelClass.ChatThinking;
|
|
179
|
+
case ModelRsModelClass.ChatBalanced:
|
|
180
|
+
return model.ModelClass.ChatBalanced;
|
|
181
|
+
case ModelRsModelClass.ChatFast:
|
|
182
|
+
return model.ModelClass.ChatFast;
|
|
183
|
+
case ModelRsModelClass.Embedding:
|
|
184
|
+
return model.ModelClass.Embedding;
|
|
185
|
+
}
|
|
199
186
|
}
|
|
200
187
|
|
|
201
188
|
/**
|
|
@@ -308,9 +295,10 @@ export async function selectModel(
|
|
|
308
295
|
* fuzzy-ranked within the (optional) class ceiling and the best taken,
|
|
309
296
|
* falling back to the input verbatim when nothing matches.
|
|
310
297
|
* 2. **No explicit ask**: an operator-pinned `fallback` that exists in the live
|
|
311
|
-
* catalogue wins first
|
|
312
|
-
*
|
|
313
|
-
*
|
|
298
|
+
* catalogue wins first. A class request ranks within that ceiling. A
|
|
299
|
+
* general request prefers the highest-ranked live GPT, then any ranked live
|
|
300
|
+
* chat model. The static {@link FALLBACK_MODEL_IDS} floor is used only when
|
|
301
|
+
* the catalogue yields nothing in range.
|
|
314
302
|
*/
|
|
315
303
|
export function resolveModel(
|
|
316
304
|
endpoints: readonly ServingEndpointSummary[],
|
|
@@ -341,9 +329,17 @@ export function resolveModel(
|
|
|
341
329
|
}
|
|
342
330
|
|
|
343
331
|
const source = input.modelClass !== undefined ? "class" : "fallback";
|
|
332
|
+
if (input.modelClass === undefined) {
|
|
333
|
+
const [preferred] = lookupModels(endpoints, buildQuery(input, DEFAULT_MODEL_FAMILY_SEARCH));
|
|
334
|
+
if (preferred) return { modelId: preferred.endpoint.name, source };
|
|
335
|
+
}
|
|
344
336
|
const [top] = lookupModels(endpoints, buildQuery(input, undefined));
|
|
345
337
|
if (top) return { modelId: top.endpoint.name, source };
|
|
346
338
|
|
|
339
|
+
if (input.liveOnly) {
|
|
340
|
+
throw new Error("No matching live Model Serving endpoint is available");
|
|
341
|
+
}
|
|
342
|
+
|
|
347
343
|
// Live catalogue yielded nothing in range: walk the static floor.
|
|
348
344
|
const floorSource =
|
|
349
345
|
input.modelClass !== undefined ? modelsForClass(input.modelClass) : (input.fallbacks ?? []);
|
package/src/serving.ts
CHANGED
|
@@ -34,6 +34,7 @@ import {
|
|
|
34
34
|
import Fuse from "fuse.js";
|
|
35
35
|
|
|
36
36
|
import { MODEL_CLASS_ORDER } from "./classes.ts";
|
|
37
|
+
import { modelFamily, modelReasoningEfforts } from "./policy.ts";
|
|
37
38
|
|
|
38
39
|
const { ModelClass } = model;
|
|
39
40
|
|
|
@@ -125,16 +126,20 @@ export async function listServingEndpointsUncached(
|
|
|
125
126
|
for await (const ep of client.servingEndpoints.list()) {
|
|
126
127
|
if (!ep.name) continue;
|
|
127
128
|
const profile = extractProfile(ep);
|
|
129
|
+
const family = modelFamily(ep.name);
|
|
130
|
+
const reasoningEfforts = modelReasoningEfforts(ep.name);
|
|
128
131
|
out.push({
|
|
129
132
|
name: ep.name,
|
|
130
133
|
// Prefer a Databricks-provided human name (a display-name tag or an
|
|
131
134
|
// external-model name); else derive a title-cased label from the id.
|
|
132
135
|
displayName: display.toModelDisplayName(ep.name, providedDisplayName(ep)),
|
|
136
|
+
...(family !== undefined ? { family } : {}),
|
|
133
137
|
...(ep.task !== undefined ? { task: ep.task } : {}),
|
|
134
138
|
...(ep.state?.ready !== undefined ? { state: String(ep.state.ready) } : {}),
|
|
135
139
|
...(ep.description !== undefined ? { description: ep.description } : {}),
|
|
136
140
|
supportsTools: classify.supportsToolsByFamily(ep.name),
|
|
137
141
|
...(profile ? { profile } : {}),
|
|
142
|
+
...(reasoningEfforts.length > 0 ? { reasoningEfforts } : {}),
|
|
138
143
|
});
|
|
139
144
|
}
|
|
140
145
|
return out;
|