semantifold 0.3.0 → 0.4.0
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 +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { SemantifoldDiagnostic } from "../diagnostic.js";
|
|
3
|
+
import { parseStdlibVersionRange } from "./stdlib.js";
|
|
4
|
+
const authoritySchema = "SemantifoldCapabilityAuthority";
|
|
5
|
+
const authorityIdPattern = /^[a-z][a-z0-9.-]*$/u;
|
|
6
|
+
const declarationNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
7
|
+
const scalarNames = new Set(["boolean", "integer", "string"]);
|
|
8
|
+
const createdAuthorities = new WeakSet();
|
|
9
|
+
/**
|
|
10
|
+
* @typedef CapabilityAuthorityV2State
|
|
11
|
+
* @property {{candidate: import("./types.js").CapabilityDeclarationInput, capabilityId: string, failures: import("./types.js").EffectFailureDeclaration[], resources: import("./types.js").EffectResourceDeclaration[]}[]} capabilities - Prepared capability declarations.
|
|
12
|
+
* @property {Map<string, string | undefined>} failureNames - Module-local failures.
|
|
13
|
+
* @property {string} identity - Canonical module identity.
|
|
14
|
+
* @property {number} moduleIndex - Stable module position.
|
|
15
|
+
* @property {Map<string, string | undefined>} resourceNames - Module-local resources.
|
|
16
|
+
* @property {string} contractVersion - Canonical contract range.
|
|
17
|
+
*/
|
|
18
|
+
const task034ProbeOperations = Object.freeze([
|
|
19
|
+
Object.freeze({ failures: Object.freeze(["capability:0/failure:0"]), flow: Object.freeze({ kind: "none" }),
|
|
20
|
+
name: "probeEffect", parameters: Object.freeze([["label", "string"], ["value", "integer"], ["fail", "boolean"]]),
|
|
21
|
+
returnType: "integer" }),
|
|
22
|
+
Object.freeze({ failures: Object.freeze(["capability:0/failure:1"]),
|
|
23
|
+
flow: Object.freeze({ kind: "acquire", resourceId: "capability:0/resource:0" }), name: "probeAcquire",
|
|
24
|
+
parameters: Object.freeze([["fail", "boolean"]]), returnType: "resource" }),
|
|
25
|
+
Object.freeze({ failures: Object.freeze(["capability:0/failure:2", "capability:0/failure:4"]),
|
|
26
|
+
flow: Object.freeze({ kind: "borrow", parameterIndex: 0, terminalFailureId: "capability:0/failure:4" }), name: "probeRead",
|
|
27
|
+
parameters: Object.freeze([["resource", "resource"], ["fail", "boolean"]]), returnType: "optional:string" }),
|
|
28
|
+
Object.freeze({ failures: Object.freeze(["capability:0/failure:3", "capability:0/failure:4"]),
|
|
29
|
+
flow: Object.freeze({ kind: "close", parameterIndex: 0, terminalFailureId: "capability:0/failure:4" }), name: "probeClose",
|
|
30
|
+
parameters: Object.freeze([["resource", "resource"], ["fail", "boolean"]]), returnType: "void" }),
|
|
31
|
+
Object.freeze({ failures: Object.freeze([]), flow: Object.freeze({ kind: "none" }), name: "probeTrace",
|
|
32
|
+
parameters: Object.freeze([]), returnType: "string" })
|
|
33
|
+
]);
|
|
34
|
+
/**
|
|
35
|
+
* Creates an immutable, detached compiler-authority descriptor.
|
|
36
|
+
* @param {unknown} input - Untrusted authority input.
|
|
37
|
+
* @returns {Readonly<import("./types.js").CapabilityAuthority>} Normalized authority.
|
|
38
|
+
*/
|
|
39
|
+
export function createCapabilityAuthority(input) {
|
|
40
|
+
try {
|
|
41
|
+
if (createdAuthorities.has(/** @type {object} */ (input)))
|
|
42
|
+
return /** @type {Readonly<import("./types.js").CapabilityAuthority>} */ (input);
|
|
43
|
+
requirePlain(input, "authority");
|
|
44
|
+
const authorityInput = /** @type {import("./types.js").CapabilityAuthorityInput} */ (input);
|
|
45
|
+
if (authorityInput.schemaVersion == 2)
|
|
46
|
+
return createCapabilityAuthorityV2(authorityInput);
|
|
47
|
+
const hasContractVersion = Object.hasOwn(authorityInput, "contractVersion");
|
|
48
|
+
requireKeys(authorityInput, hasContractVersion
|
|
49
|
+
? ["capabilities", "contractVersion", "id", "schema", "schemaVersion"]
|
|
50
|
+
: ["capabilities", "id", "schema", "schemaVersion"], "authority");
|
|
51
|
+
if (hasContractVersion && parseStdlibVersionRange(authorityInput.contractVersion) === null) {
|
|
52
|
+
throw new SemantifoldDiagnostic({
|
|
53
|
+
code: "STDLIB_VERSION_MALFORMED",
|
|
54
|
+
language: "capability",
|
|
55
|
+
message: "Capability authority contractVersion is not a canonical stdlib version range."
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (authorityInput.schema != authoritySchema || authorityInput.schemaVersion != 1 || typeof authorityInput.id != "string" ||
|
|
59
|
+
!authorityIdPattern.test(authorityInput.id) || !dense(authorityInput.capabilities))
|
|
60
|
+
invalid("Authority schema, version, identity, or capability list is invalid.");
|
|
61
|
+
const capabilityNames = new Set();
|
|
62
|
+
const authorityResourceNames = new Set();
|
|
63
|
+
const authorityFailureNames = new Set();
|
|
64
|
+
const authorityOperationNames = new Set();
|
|
65
|
+
const capabilities = authorityInput.capabilities.map((candidate, capabilityIndex) => {
|
|
66
|
+
requirePlain(candidate, `capability ${capabilityIndex}`);
|
|
67
|
+
requireKeys(candidate, ["failures", "name", "operations", "resources"], `capability ${capabilityIndex}`);
|
|
68
|
+
requireName(candidate.name, capabilityNames, "capability");
|
|
69
|
+
if (!dense(candidate.resources) || !dense(candidate.failures) || !dense(candidate.operations)) {
|
|
70
|
+
invalid(`Capability '${candidate.name}' requires ordered resource, failure, and operation arrays.`);
|
|
71
|
+
}
|
|
72
|
+
const capabilityId = `capability:${capabilityIndex}`;
|
|
73
|
+
const resourceNames = new Map();
|
|
74
|
+
const resources = candidate.resources.map((resource, resourceIndex) => {
|
|
75
|
+
requireNamed(resource, resourceNames, "resource");
|
|
76
|
+
requireName(resource.name, authorityResourceNames, "authority resource");
|
|
77
|
+
const id = `${capabilityId}/resource:${resourceIndex}`;
|
|
78
|
+
resourceNames.set(resource.name, id);
|
|
79
|
+
return { id, kind: /** @type {const} */ ("EffectResourceDeclaration"), name: resource.name };
|
|
80
|
+
});
|
|
81
|
+
const failureNames = new Map();
|
|
82
|
+
const failures = candidate.failures.map((failure, failureIndex) => {
|
|
83
|
+
requireNamed(failure, failureNames, "failure");
|
|
84
|
+
requireName(failure.name, authorityFailureNames, "authority failure");
|
|
85
|
+
const id = `${capabilityId}/failure:${failureIndex}`;
|
|
86
|
+
failureNames.set(failure.name, id);
|
|
87
|
+
return { id, kind: /** @type {const} */ ("EffectFailureDeclaration"), name: failure.name };
|
|
88
|
+
});
|
|
89
|
+
const operationNames = new Set();
|
|
90
|
+
const operations = candidate.operations.map((operation, operationIndex) => {
|
|
91
|
+
requirePlain(operation, `operation ${operationIndex}`);
|
|
92
|
+
requireKeys(operation, ["effects", "failures", "name", "parameters", "resourceFlow", "returnType"], `operation ${operationIndex}`);
|
|
93
|
+
requireName(operation.name, operationNames, "operation");
|
|
94
|
+
requireName(operation.name, authorityOperationNames, "authority operation");
|
|
95
|
+
if (!dense(operation.parameters) || !dense(operation.failures) || !dense(operation.effects) ||
|
|
96
|
+
operation.effects.length != 1 || operation.effects[0] != "host")
|
|
97
|
+
invalid(`Operation '${operation.name}' has an invalid effect declaration.`);
|
|
98
|
+
const parameterNames = new Set();
|
|
99
|
+
const parameters = operation.parameters.map((parameter, parameterIndex) => {
|
|
100
|
+
requirePlain(parameter, `parameter ${parameterIndex}`);
|
|
101
|
+
requireKeys(parameter, ["name", "type"], `parameter ${parameterIndex}`);
|
|
102
|
+
requireName(parameter.name, parameterNames, "parameter");
|
|
103
|
+
return { name: parameter.name, type: normalizeValueType(parameter.type, resourceNames) };
|
|
104
|
+
});
|
|
105
|
+
const returnType = operation.returnType == "void" ? { kind: /** @type {const} */ ("TypeReference"), name: /** @type {const} */ ("void") } :
|
|
106
|
+
normalizeValueType(operation.returnType, resourceNames);
|
|
107
|
+
const failureIds = operation.failures.map((name) => {
|
|
108
|
+
if (typeof name != "string" || !failureNames.has(name))
|
|
109
|
+
invalid(`Operation '${operation.name}' names an undeclared failure '${String(name)}'.`);
|
|
110
|
+
return /** @type {string} */ (failureNames.get(name));
|
|
111
|
+
});
|
|
112
|
+
if (new Set(failureIds).size != failureIds.length)
|
|
113
|
+
invalid(`Operation '${operation.name}' repeats a declared failure.`);
|
|
114
|
+
const resourceFlow = normalizeResourceFlow(operation.resourceFlow, resources, resourceNames, failureNames, parameters);
|
|
115
|
+
validateResourceOperation(operation.name, parameters, returnType, failureIds, resourceFlow);
|
|
116
|
+
return {
|
|
117
|
+
effects: /** @type {const} */ (["host"]),
|
|
118
|
+
failureIds,
|
|
119
|
+
id: `${capabilityId}/operation:${operationIndex}`,
|
|
120
|
+
kind: /** @type {const} */ ("EffectOperationDeclaration"),
|
|
121
|
+
name: operation.name,
|
|
122
|
+
parameters,
|
|
123
|
+
resourceFlow,
|
|
124
|
+
returnType
|
|
125
|
+
};
|
|
126
|
+
});
|
|
127
|
+
return {
|
|
128
|
+
authorityId: authorityInput.id,
|
|
129
|
+
failures,
|
|
130
|
+
id: capabilityId,
|
|
131
|
+
kind: /** @type {const} */ ("EffectCapabilityDeclaration"),
|
|
132
|
+
name: candidate.name,
|
|
133
|
+
operations,
|
|
134
|
+
resources
|
|
135
|
+
};
|
|
136
|
+
});
|
|
137
|
+
const result = /** @type {import("./types.js").CapabilityAuthority} */ ({
|
|
138
|
+
capabilities,
|
|
139
|
+
id: authorityInput.id,
|
|
140
|
+
schema: authoritySchema,
|
|
141
|
+
schemaVersion: 1,
|
|
142
|
+
...(hasContractVersion ? { contractVersion: /** @type {string} */ (authorityInput.contractVersion) } : {})
|
|
143
|
+
});
|
|
144
|
+
deepFreeze(result);
|
|
145
|
+
createdAuthorities.add(result);
|
|
146
|
+
return result;
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
if (error instanceof SemantifoldDiagnostic)
|
|
150
|
+
throw error;
|
|
151
|
+
return invalid("Authority payload is malformed.");
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Normalizes a strict multi-module schema-v2 authority.
|
|
156
|
+
* @param {import("./types.js").CapabilityAuthorityInput} authorityInput - Validated outer object candidate.
|
|
157
|
+
* @returns {Readonly<import("./types.js").CapabilityAuthority>} Normalized authority.
|
|
158
|
+
*/
|
|
159
|
+
function createCapabilityAuthorityV2(authorityInput) {
|
|
160
|
+
requireKeys(/** @type {Record<string, unknown>} */ (authorityInput), ["id", "modules", "schema", "schemaVersion"], "authority");
|
|
161
|
+
if (authorityInput.schema != authoritySchema || authorityInput.schemaVersion != 2 ||
|
|
162
|
+
typeof authorityInput.id != "string" || !authorityIdPattern.test(authorityInput.id) || !dense(authorityInput.modules)) {
|
|
163
|
+
invalid("Authority schema, version, identity, or module list is invalid.");
|
|
164
|
+
}
|
|
165
|
+
const identities = new Set();
|
|
166
|
+
const moduleInputs = authorityInput.modules.map((candidate, moduleIndex) => {
|
|
167
|
+
requirePlain(candidate, `module ${moduleIndex}`);
|
|
168
|
+
requireKeys(candidate, ["capabilities", "contractVersion", "identity"], `module ${moduleIndex}`);
|
|
169
|
+
if (typeof candidate.identity != "string" || !authorityIdPattern.test(candidate.identity) || identities.has(candidate.identity) ||
|
|
170
|
+
parseStdlibVersionRange(candidate.contractVersion) === null || !dense(candidate.capabilities)) {
|
|
171
|
+
invalid(`Authority module ${moduleIndex} is invalid or duplicate.`);
|
|
172
|
+
}
|
|
173
|
+
identities.add(candidate.identity);
|
|
174
|
+
return candidate;
|
|
175
|
+
});
|
|
176
|
+
const states = moduleInputs.map((moduleInput, moduleIndex) => {
|
|
177
|
+
const resourceNames = new Map();
|
|
178
|
+
const failureNames = new Map();
|
|
179
|
+
const capabilityNames = new Set();
|
|
180
|
+
const capabilities = moduleInput.capabilities.map((candidate, capabilityIndex) => {
|
|
181
|
+
requirePlain(candidate, `module ${moduleIndex} capability ${capabilityIndex}`);
|
|
182
|
+
requireKeys(candidate, ["failures", "name", "operations", "resources"], `module ${moduleIndex} capability ${capabilityIndex}`);
|
|
183
|
+
requireName(candidate.name, capabilityNames, "capability");
|
|
184
|
+
if (!dense(candidate.resources) || !dense(candidate.failures) || !dense(candidate.operations)) {
|
|
185
|
+
invalid(`Capability '${candidate.name}' requires ordered resource, failure, and operation arrays.`);
|
|
186
|
+
}
|
|
187
|
+
const capabilityId = `module:${moduleIndex}/capability:${capabilityIndex}`;
|
|
188
|
+
const resources = candidate.resources.map((resource, resourceIndex) => {
|
|
189
|
+
requireNamed(resource, resourceNames, "module resource");
|
|
190
|
+
const id = `${capabilityId}/resource:${resourceIndex}`;
|
|
191
|
+
resourceNames.set(resource.name, id);
|
|
192
|
+
return { id, kind: /** @type {const} */ ("EffectResourceDeclaration"), name: resource.name };
|
|
193
|
+
});
|
|
194
|
+
const failures = candidate.failures.map((failure, failureIndex) => {
|
|
195
|
+
requireNamed(failure, failureNames, "module failure");
|
|
196
|
+
const id = `${capabilityId}/failure:${failureIndex}`;
|
|
197
|
+
failureNames.set(failure.name, id);
|
|
198
|
+
return { id, kind: /** @type {const} */ ("EffectFailureDeclaration"), name: failure.name };
|
|
199
|
+
});
|
|
200
|
+
return { candidate, capabilityId, failures, resources };
|
|
201
|
+
});
|
|
202
|
+
return { capabilities, failureNames, identity: moduleInput.identity, moduleIndex, resourceNames,
|
|
203
|
+
contractVersion: moduleInput.contractVersion };
|
|
204
|
+
});
|
|
205
|
+
const operationNames = new Set();
|
|
206
|
+
const normalizedModules = states.map((state) => {
|
|
207
|
+
const capabilities = state.capabilities.map((capabilityState) => {
|
|
208
|
+
const localOperationNames = new Set();
|
|
209
|
+
const operations = capabilityState.candidate.operations.map((operation, operationIndex) => {
|
|
210
|
+
requirePlain(operation, `module ${state.moduleIndex} operation ${operationIndex}`);
|
|
211
|
+
requireKeys(operation, ["effects", "failures", "name", "parameters", "resourceFlow", "returnType"], `module ${state.moduleIndex} operation ${operationIndex}`);
|
|
212
|
+
requireName(operation.name, localOperationNames, "operation");
|
|
213
|
+
const qualifiedOperationName = `${state.identity}\u0000${operation.name}`;
|
|
214
|
+
if (operationNames.has(qualifiedOperationName))
|
|
215
|
+
invalid(`Duplicate authority operation '${operation.name}'.`);
|
|
216
|
+
operationNames.add(qualifiedOperationName);
|
|
217
|
+
if (!dense(operation.parameters) || !dense(operation.failures) || !dense(operation.effects) ||
|
|
218
|
+
operation.effects.length != 1 || operation.effects[0] != "host") {
|
|
219
|
+
invalid(`Operation '${operation.name}' has an invalid effect declaration.`);
|
|
220
|
+
}
|
|
221
|
+
const parameterNames = new Set();
|
|
222
|
+
const parameters = operation.parameters.map((parameter, parameterIndex) => {
|
|
223
|
+
requirePlain(parameter, `parameter ${parameterIndex}`);
|
|
224
|
+
requireKeys(parameter, ["name", "type"], `parameter ${parameterIndex}`);
|
|
225
|
+
requireName(parameter.name, parameterNames, "parameter");
|
|
226
|
+
return { name: parameter.name, type: normalizeV2ValueType(parameter.type, state, states) };
|
|
227
|
+
});
|
|
228
|
+
const returnType = operation.returnType == "void"
|
|
229
|
+
? { kind: /** @type {const} */ ("TypeReference"), name: /** @type {const} */ ("void") }
|
|
230
|
+
: normalizeV2ValueType(operation.returnType, state, states);
|
|
231
|
+
const failureIds = operation.failures.map((failure) => resolveV2Declaration(failure, state, states, "failure"));
|
|
232
|
+
if (new Set(failureIds).size != failureIds.length)
|
|
233
|
+
invalid(`Operation '${operation.name}' repeats a declared failure.`);
|
|
234
|
+
const resourceFlow = normalizeV2ResourceFlow(operation.resourceFlow, parameters, state, states);
|
|
235
|
+
validateResourceOperation(operation.name, parameters, returnType, failureIds, resourceFlow);
|
|
236
|
+
return {
|
|
237
|
+
effects: /** @type {const} */ (["host"]),
|
|
238
|
+
failureIds,
|
|
239
|
+
id: `${capabilityState.capabilityId}/operation:${operationIndex}`,
|
|
240
|
+
kind: /** @type {const} */ ("EffectOperationDeclaration"),
|
|
241
|
+
name: operation.name,
|
|
242
|
+
parameters,
|
|
243
|
+
resourceFlow,
|
|
244
|
+
returnType
|
|
245
|
+
};
|
|
246
|
+
});
|
|
247
|
+
return {
|
|
248
|
+
authorityId: state.identity,
|
|
249
|
+
failures: capabilityState.failures,
|
|
250
|
+
id: capabilityState.capabilityId,
|
|
251
|
+
kind: /** @type {const} */ ("EffectCapabilityDeclaration"),
|
|
252
|
+
name: capabilityState.candidate.name,
|
|
253
|
+
operations,
|
|
254
|
+
resources: capabilityState.resources
|
|
255
|
+
};
|
|
256
|
+
});
|
|
257
|
+
return { capabilities, contractVersion: state.contractVersion, identity: state.identity };
|
|
258
|
+
});
|
|
259
|
+
const result = /** @type {import("./types.js").CapabilityAuthority} */ ({
|
|
260
|
+
capabilities: normalizedModules.flatMap(({ capabilities }) => capabilities),
|
|
261
|
+
id: authorityInput.id,
|
|
262
|
+
modules: normalizedModules,
|
|
263
|
+
schema: authoritySchema,
|
|
264
|
+
schemaVersion: 2
|
|
265
|
+
});
|
|
266
|
+
deepFreeze(result);
|
|
267
|
+
createdAuthorities.add(result);
|
|
268
|
+
return result;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Normalizes one schema-v2 value type.
|
|
272
|
+
* @param {unknown} candidate - Candidate type.
|
|
273
|
+
* @param {CapabilityAuthorityV2State} state - Current module state.
|
|
274
|
+
* @param {CapabilityAuthorityV2State[]} states - Complete authority states.
|
|
275
|
+
* @returns {import("./types.js").SemanticValueType} Normalized type.
|
|
276
|
+
*/
|
|
277
|
+
function normalizeV2ValueType(candidate, state, states) {
|
|
278
|
+
if (typeof candidate == "string" && scalarNames.has(candidate)) {
|
|
279
|
+
return { kind: /** @type {const} */ ("TypeReference"), name: /** @type {import("./types.js").SemanticTypeName} */ (candidate) };
|
|
280
|
+
}
|
|
281
|
+
requirePlain(candidate, "operation type");
|
|
282
|
+
if (candidate.kind == "OwnedResourceType") {
|
|
283
|
+
requireKeys(candidate, ["kind", "resource"], "owned resource type");
|
|
284
|
+
return { kind: /** @type {const} */ ("OwnedResourceType"), resourceId: resolveV2Declaration(candidate.resource, state, states, "resource") };
|
|
285
|
+
}
|
|
286
|
+
if (candidate.kind == "OptionalType") {
|
|
287
|
+
requireKeys(candidate, ["kind", "valueType"], "optional type");
|
|
288
|
+
if (typeof candidate.valueType != "string" || !scalarNames.has(candidate.valueType)) {
|
|
289
|
+
invalid("Capability optionals may contain only scalar values.");
|
|
290
|
+
}
|
|
291
|
+
return { kind: /** @type {const} */ ("OptionalType"), valueType: { kind: /** @type {const} */ ("TypeReference"),
|
|
292
|
+
name: /** @type {import("./types.js").SemanticTypeName} */ (candidate.valueType) } };
|
|
293
|
+
}
|
|
294
|
+
return invalid("Unsupported capability value type.");
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Normalizes one schema-v2 resource transition.
|
|
298
|
+
* @param {unknown} candidate - Candidate transition.
|
|
299
|
+
* @param {import("./types.js").EffectParameter[]} parameters - Normalized parameters.
|
|
300
|
+
* @param {CapabilityAuthorityV2State} state - Current module state.
|
|
301
|
+
* @param {CapabilityAuthorityV2State[]} states - Complete authority states.
|
|
302
|
+
* @returns {import("./types.js").EffectResourceFlow} Normalized transition.
|
|
303
|
+
*/
|
|
304
|
+
function normalizeV2ResourceFlow(candidate, parameters, state, states) {
|
|
305
|
+
requirePlain(candidate, "resource flow");
|
|
306
|
+
if (candidate.kind == "none") {
|
|
307
|
+
requireKeys(candidate, ["kind"], "resource flow");
|
|
308
|
+
return { kind: /** @type {const} */ ("none") };
|
|
309
|
+
}
|
|
310
|
+
if (candidate.kind == "acquire") {
|
|
311
|
+
requireKeys(candidate, ["kind", "resource"], "acquisition flow");
|
|
312
|
+
return { kind: /** @type {const} */ ("acquire"), resourceId: resolveV2Declaration(candidate.resource, state, states, "resource") };
|
|
313
|
+
}
|
|
314
|
+
if (candidate.kind == "borrow" || candidate.kind == "close") {
|
|
315
|
+
requireKeys(candidate, ["kind", "parameterIndex", "terminalFailure"], `${candidate.kind} flow`);
|
|
316
|
+
const parameterIndex = /** @type {number} */ (candidate.parameterIndex);
|
|
317
|
+
if (!Number.isSafeInteger(parameterIndex) || parameterIndex < 0 || parameterIndex >= parameters.length ||
|
|
318
|
+
parameters[parameterIndex].type.kind != "OwnedResourceType")
|
|
319
|
+
invalid(`${candidate.kind} flow requires an owned resource parameter.`);
|
|
320
|
+
return { kind: /** @type {"borrow" | "close"} */ (candidate.kind), parameterIndex,
|
|
321
|
+
terminalFailureId: resolveV2Declaration(candidate.terminalFailure, state, states, "failure") };
|
|
322
|
+
}
|
|
323
|
+
return invalid("Unknown resource-flow kind.");
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Resolves one local or qualified schema-v2 resource/failure reference.
|
|
327
|
+
* @param {unknown} candidate - Candidate reference.
|
|
328
|
+
* @param {CapabilityAuthorityV2State} state - Current module state.
|
|
329
|
+
* @param {CapabilityAuthorityV2State[]} states - Complete authority states.
|
|
330
|
+
* @param {"resource" | "failure"} kind - Declaration namespace.
|
|
331
|
+
* @returns {string} Normalized declaration identity.
|
|
332
|
+
*/
|
|
333
|
+
function resolveV2Declaration(candidate, state, states, kind) {
|
|
334
|
+
/** @type {CapabilityAuthorityV2State | undefined} */
|
|
335
|
+
let owner = state;
|
|
336
|
+
let name = candidate;
|
|
337
|
+
if (candidate !== null && typeof candidate == "object" && !Array.isArray(candidate)) {
|
|
338
|
+
requirePlain(candidate, `${kind} reference`);
|
|
339
|
+
requireKeys(candidate, ["module", "name"], `${kind} reference`);
|
|
340
|
+
if (typeof candidate.module != "string" || typeof candidate.name != "string")
|
|
341
|
+
invalid(`Invalid qualified ${kind} reference.`);
|
|
342
|
+
owner = states.find(({ identity }) => identity == candidate.module);
|
|
343
|
+
name = candidate.name;
|
|
344
|
+
}
|
|
345
|
+
if (!owner || typeof name != "string")
|
|
346
|
+
invalid(`Unknown ${kind} reference.`);
|
|
347
|
+
const declarations = kind == "resource" ? owner.resourceNames : owner.failureNames;
|
|
348
|
+
const id = declarations.get(name);
|
|
349
|
+
if (id === undefined)
|
|
350
|
+
invalid(`Unknown ${kind} '${owner.identity}.${name}'.`);
|
|
351
|
+
return id;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Normalizes an optional parse authority.
|
|
355
|
+
* @param {unknown} input - Optional caller input.
|
|
356
|
+
* @returns {Readonly<import("./types.js").CapabilityAuthority> | undefined} Authority or legacy absence.
|
|
357
|
+
*/
|
|
358
|
+
export function normalizeCapabilityAuthority(input) {
|
|
359
|
+
return input === undefined ? undefined : createCapabilityAuthority(input);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Finds one source-visible operation only when an ordinary source declaration did not win resolution.
|
|
363
|
+
* @param {readonly import("./types.js").EffectCapabilityDeclaration[]} capabilities - Authorized declarations.
|
|
364
|
+
* @param {string} name - Source spelling.
|
|
365
|
+
* @returns {{capability: import("./types.js").EffectCapabilityDeclaration, operation: import("./types.js").EffectOperationDeclaration} | undefined} Match.
|
|
366
|
+
*/
|
|
367
|
+
export function authorizedOperation(capabilities, name) {
|
|
368
|
+
for (const capability of capabilities) {
|
|
369
|
+
const operation = capability.operations.find((candidate) => candidate.name == name);
|
|
370
|
+
if (operation)
|
|
371
|
+
return { capability, operation };
|
|
372
|
+
}
|
|
373
|
+
return undefined;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Checks the bounded conformance operation namespace.
|
|
377
|
+
* @param {string} name - Candidate source name.
|
|
378
|
+
* @returns {boolean} Whether the name belongs to Task 034.
|
|
379
|
+
*/
|
|
380
|
+
export function isTask034OperationName(name) {
|
|
381
|
+
return ["probeAcquire", "probeClose", "probeEffect", "probeRead", "probeTrace"].includes(name);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Checks the exact built-in conformance capability identity.
|
|
385
|
+
* @param {readonly import("./types.js").EffectCapabilityDeclaration[]} capabilities - Candidate graph.
|
|
386
|
+
* @returns {boolean} Whether the graph has the supported identity and declaration order.
|
|
387
|
+
*/
|
|
388
|
+
export function isTask034ResourceProbe(capabilities) {
|
|
389
|
+
if (!dense(capabilities) || capabilities.length != 1)
|
|
390
|
+
return false;
|
|
391
|
+
const capability = capabilities[0];
|
|
392
|
+
if (!plainWithKeys(capability, ["authorityId", "failures", "id", "kind", "name", "operations", "resources"]) ||
|
|
393
|
+
capability.authorityId != "semantifold.task034.resource-probe" || capability.id != "capability:0" ||
|
|
394
|
+
capability.kind != "EffectCapabilityDeclaration" || capability.name != "ResourceProbe" ||
|
|
395
|
+
!dense(capability.resources) || !dense(capability.failures) || !dense(capability.operations) ||
|
|
396
|
+
capability.resources.length != 1 || capability.failures.length != 5 || capability.operations.length != 5)
|
|
397
|
+
return false;
|
|
398
|
+
if (!exactNamedDeclaration(capability.resources[0], "EffectResourceDeclaration", "capability:0/resource:0", "ProbeResource"))
|
|
399
|
+
return false;
|
|
400
|
+
const expectedFailures = ["ProbeOperationFailure", "ProbeAcquireFailure", "ProbeReadFailure", "ProbeCloseFailure", "ProbeResourceClosed"];
|
|
401
|
+
if (!capability.failures.every((failure, index) => exactNamedDeclaration(failure, "EffectFailureDeclaration", `capability:0/failure:${index}`, expectedFailures[index])))
|
|
402
|
+
return false;
|
|
403
|
+
return capability.operations.every((operation, index) => exactProbeOperation(operation, index, task034ProbeOperations[index]));
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Checks one exact normalized declaration.
|
|
407
|
+
* @param {unknown} candidate - Candidate declaration.
|
|
408
|
+
* @param {string} kind - Expected kind.
|
|
409
|
+
* @param {string} id - Expected identity.
|
|
410
|
+
* @param {string} name - Expected source name.
|
|
411
|
+
* @returns {boolean} Whether the declaration is exact.
|
|
412
|
+
*/
|
|
413
|
+
function exactNamedDeclaration(candidate, kind, id, name) {
|
|
414
|
+
return plainWithKeys(candidate, ["id", "kind", "name"]) && candidate.kind == kind && candidate.id == id && candidate.name == name;
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Checks one exact Task 034 conformance operation.
|
|
418
|
+
* @param {unknown} candidate - Candidate operation.
|
|
419
|
+
* @param {number} index - Expected operation index.
|
|
420
|
+
* @param {(typeof task034ProbeOperations)[number]} expected - Exact contract.
|
|
421
|
+
* @returns {boolean} Whether the operation matches the protected binding.
|
|
422
|
+
*/
|
|
423
|
+
function exactProbeOperation(candidate, index, expected) {
|
|
424
|
+
if (!plainWithKeys(candidate, ["effects", "failureIds", "id", "kind", "name", "parameters", "resourceFlow", "returnType"]) ||
|
|
425
|
+
candidate.kind != "EffectOperationDeclaration" || candidate.id != `capability:0/operation:${index}` ||
|
|
426
|
+
candidate.name != expected.name || !sameStringArray(candidate.effects, ["host"]) ||
|
|
427
|
+
!sameStringArray(candidate.failureIds, expected.failures) || !dense(candidate.parameters) ||
|
|
428
|
+
candidate.parameters.length != expected.parameters.length || !exactFlatObject(candidate.resourceFlow, expected.flow) ||
|
|
429
|
+
!exactProbeType(candidate.returnType, expected.returnType))
|
|
430
|
+
return false;
|
|
431
|
+
return candidate.parameters.every((parameter, parameterIndex) => plainWithKeys(parameter, ["name", "type"]) &&
|
|
432
|
+
parameter.name == expected.parameters[parameterIndex][0] && exactProbeType(parameter.type, expected.parameters[parameterIndex][1]));
|
|
433
|
+
}
|
|
434
|
+
/**
|
|
435
|
+
* Checks one exact normalized conformance type.
|
|
436
|
+
* @param {unknown} candidate - Candidate type.
|
|
437
|
+
* @param {string} expected - Compact expected type.
|
|
438
|
+
* @returns {boolean} Whether the type is exact.
|
|
439
|
+
*/
|
|
440
|
+
function exactProbeType(candidate, expected) {
|
|
441
|
+
if (expected == "resource") {
|
|
442
|
+
return plainWithKeys(candidate, ["kind", "resourceId"]) && candidate.kind == "OwnedResourceType" &&
|
|
443
|
+
candidate.resourceId == "capability:0/resource:0";
|
|
444
|
+
}
|
|
445
|
+
if (expected == "optional:string") {
|
|
446
|
+
return plainWithKeys(candidate, ["kind", "valueType"]) && candidate.kind == "OptionalType" &&
|
|
447
|
+
exactProbeType(candidate.valueType, "string");
|
|
448
|
+
}
|
|
449
|
+
return plainWithKeys(candidate, ["kind", "name"]) && candidate.kind == "TypeReference" && candidate.name == expected;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Checks an exact shallow object of primitive contract fields.
|
|
453
|
+
* @param {unknown} candidate - Candidate object.
|
|
454
|
+
* @param {Readonly<Record<string, unknown>>} expected - Expected fields.
|
|
455
|
+
* @returns {boolean} Whether all fields and values match.
|
|
456
|
+
*/
|
|
457
|
+
function exactFlatObject(candidate, expected) {
|
|
458
|
+
const keys = Object.keys(expected);
|
|
459
|
+
return plainWithKeys(candidate, keys) && keys.every((key) => candidate[key] == expected[key]);
|
|
460
|
+
}
|
|
461
|
+
/**
|
|
462
|
+
* Checks an exact dense string sequence.
|
|
463
|
+
* @param {unknown} candidate - Candidate sequence.
|
|
464
|
+
* @param {readonly string[]} expected - Expected strings.
|
|
465
|
+
* @returns {boolean} Whether order and values match.
|
|
466
|
+
*/
|
|
467
|
+
function sameStringArray(candidate, expected) {
|
|
468
|
+
return dense(candidate) && candidate.length == expected.length && candidate.every((value, index) => value == expected[index]);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Checks an ordinary object's exact own-key set.
|
|
472
|
+
* @param {unknown} candidate - Candidate object.
|
|
473
|
+
* @param {string[]} keys - Exact keys.
|
|
474
|
+
* @returns {candidate is Record<string, unknown>} Whether the object and fields are exact.
|
|
475
|
+
*/
|
|
476
|
+
function plainWithKeys(candidate, keys) {
|
|
477
|
+
return candidate !== null && typeof candidate == "object" && !Array.isArray(candidate) &&
|
|
478
|
+
Object.getPrototypeOf(candidate) == Object.prototype && Object.keys(candidate).sort().join(",") == [...keys].sort().join(",");
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Normalizes one closed operation value type.
|
|
482
|
+
* @param {unknown} candidate - Raw value type.
|
|
483
|
+
* @param {Map<string, string>} resourceNames - Resource identities by name.
|
|
484
|
+
* @returns {import("./types.js").SemanticValueType} Normalized type.
|
|
485
|
+
*/
|
|
486
|
+
function normalizeValueType(candidate, resourceNames) {
|
|
487
|
+
if (typeof candidate == "string" && scalarNames.has(candidate)) {
|
|
488
|
+
return { kind: /** @type {const} */ ("TypeReference"), name: /** @type {import("./types.js").SemanticTypeName} */ (candidate) };
|
|
489
|
+
}
|
|
490
|
+
requirePlain(candidate, "operation type");
|
|
491
|
+
if (candidate.kind == "OwnedResourceType") {
|
|
492
|
+
requireKeys(candidate, ["kind", "resource"], "owned resource type");
|
|
493
|
+
if (typeof candidate.resource != "string" || !resourceNames.has(candidate.resource))
|
|
494
|
+
invalid(`Unknown owned resource '${String(candidate.resource)}'.`);
|
|
495
|
+
return { kind: /** @type {const} */ ("OwnedResourceType"), resourceId: /** @type {string} */ (resourceNames.get(candidate.resource)) };
|
|
496
|
+
}
|
|
497
|
+
if (candidate.kind == "OptionalType") {
|
|
498
|
+
requireKeys(candidate, ["kind", "valueType"], "optional type");
|
|
499
|
+
if (typeof candidate.valueType != "string" || !scalarNames.has(candidate.valueType))
|
|
500
|
+
invalid("Capability optionals may contain only scalar values.");
|
|
501
|
+
return { kind: /** @type {const} */ ("OptionalType"), valueType: { kind: /** @type {const} */ ("TypeReference"),
|
|
502
|
+
name: /** @type {import("./types.js").SemanticTypeName} */ (candidate.valueType) } };
|
|
503
|
+
}
|
|
504
|
+
return invalid("Unsupported capability value type.");
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Normalizes one closed resource transition.
|
|
508
|
+
* @param {unknown} candidate - Raw transition.
|
|
509
|
+
* @param {import("./types.js").EffectResourceDeclaration[]} resources - Declared resources.
|
|
510
|
+
* @param {Map<string, string>} resourceNames - Resource identities by name.
|
|
511
|
+
* @param {Map<string, string>} failureNames - Failure identities by name.
|
|
512
|
+
* @param {import("./types.js").EffectParameter[]} parameters - Normalized ordered parameters.
|
|
513
|
+
* @returns {import("./types.js").EffectResourceFlow} Normalized flow.
|
|
514
|
+
*/
|
|
515
|
+
function normalizeResourceFlow(candidate, resources, resourceNames, failureNames, parameters) {
|
|
516
|
+
requirePlain(candidate, "resource flow");
|
|
517
|
+
if (candidate.kind == "none") {
|
|
518
|
+
requireKeys(candidate, ["kind"], "resource flow");
|
|
519
|
+
return { kind: /** @type {const} */ ("none") };
|
|
520
|
+
}
|
|
521
|
+
if (candidate.kind == "acquire") {
|
|
522
|
+
requireKeys(candidate, ["kind", "resource"], "acquisition flow");
|
|
523
|
+
if (typeof candidate.resource != "string" || !resourceNames.has(candidate.resource))
|
|
524
|
+
invalid("Acquisition names an undeclared resource.");
|
|
525
|
+
const resourceId = resourceNames.get(candidate.resource);
|
|
526
|
+
if (!resources.some(({ id }) => id == resourceId))
|
|
527
|
+
invalid("Acquisition resource identity is invalid.");
|
|
528
|
+
return { kind: /** @type {const} */ ("acquire"), resourceId: /** @type {string} */ (resourceId) };
|
|
529
|
+
}
|
|
530
|
+
if (candidate.kind == "borrow" || candidate.kind == "close") {
|
|
531
|
+
requireKeys(candidate, ["kind", "parameterIndex", "terminalFailure"], `${candidate.kind} flow`);
|
|
532
|
+
const parameterIndex = /** @type {number} */ (candidate.parameterIndex);
|
|
533
|
+
if (!Number.isSafeInteger(parameterIndex) || parameterIndex < 0 || parameterIndex >= parameters.length ||
|
|
534
|
+
parameters[parameterIndex].type.kind != "OwnedResourceType")
|
|
535
|
+
invalid(`${candidate.kind} flow requires an owned resource parameter.`);
|
|
536
|
+
if (typeof candidate.terminalFailure != "string" || !failureNames.has(candidate.terminalFailure)) {
|
|
537
|
+
invalid(`${candidate.kind} flow requires a declared terminal failure.`);
|
|
538
|
+
}
|
|
539
|
+
return { kind: /** @type {"borrow" | "close"} */ (candidate.kind), parameterIndex,
|
|
540
|
+
terminalFailureId: /** @type {string} */ (failureNames.get(candidate.terminalFailure)) };
|
|
541
|
+
}
|
|
542
|
+
return invalid("Unknown resource-flow kind.");
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Requires every owned parameter/result to have one complete modeled transition.
|
|
546
|
+
* @param {string} name - Operation name.
|
|
547
|
+
* @param {import("./types.js").EffectParameter[]} parameters - Ordered parameters.
|
|
548
|
+
* @param {import("./types.js").SemanticFunctionReturnType} returnType - Operation result.
|
|
549
|
+
* @param {string[]} failureIds - Declared failure identities.
|
|
550
|
+
* @param {import("./types.js").EffectResourceFlow} resourceFlow - Declared transition.
|
|
551
|
+
* @returns {void}
|
|
552
|
+
*/
|
|
553
|
+
function validateResourceOperation(name, parameters, returnType, failureIds, resourceFlow) {
|
|
554
|
+
const ownedParameters = parameters.flatMap((parameter, index) => parameter.type.kind == "OwnedResourceType" ? [index] : []);
|
|
555
|
+
if (resourceFlow.kind == "none") {
|
|
556
|
+
if (ownedParameters.length > 0 || returnType.kind == "OwnedResourceType") {
|
|
557
|
+
invalid(`Operation '${name}' has an owned value without a resource transition.`);
|
|
558
|
+
}
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
if (resourceFlow.kind == "acquire") {
|
|
562
|
+
if (ownedParameters.length > 0 || returnType.kind != "OwnedResourceType" || returnType.resourceId != resourceFlow.resourceId) {
|
|
563
|
+
invalid(`Operation '${name}' acquisition result does not match its resource transition.`);
|
|
564
|
+
}
|
|
565
|
+
return;
|
|
566
|
+
}
|
|
567
|
+
if (ownedParameters.length != 1 || ownedParameters[0] != resourceFlow.parameterIndex ||
|
|
568
|
+
returnType.kind == "OwnedResourceType" || !failureIds.includes(resourceFlow.terminalFailureId)) {
|
|
569
|
+
invalid(`Operation '${name}' borrow/close transition is incomplete.`);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Validates one single-field named declaration.
|
|
574
|
+
* @param {unknown} candidate - Raw declaration.
|
|
575
|
+
* @param {Map<string, string | undefined>} names - Already-declared names.
|
|
576
|
+
* @param {string} subject - Diagnostic subject.
|
|
577
|
+
* @returns {void}
|
|
578
|
+
*/
|
|
579
|
+
function requireNamed(candidate, names, subject) {
|
|
580
|
+
requirePlain(candidate, subject);
|
|
581
|
+
requireKeys(candidate, ["name"], subject);
|
|
582
|
+
if (typeof candidate.name != "string" || !declarationNamePattern.test(candidate.name) || names.has(candidate.name)) {
|
|
583
|
+
invalid(`Duplicate or invalid ${subject} name.`);
|
|
584
|
+
}
|
|
585
|
+
names.set(candidate.name, undefined);
|
|
586
|
+
}
|
|
587
|
+
/**
|
|
588
|
+
* Validates and reserves one declaration name.
|
|
589
|
+
* @param {unknown} name - Candidate name.
|
|
590
|
+
* @param {Set<string>} names - Already-declared names.
|
|
591
|
+
* @param {string} subject - Diagnostic subject.
|
|
592
|
+
* @returns {void}
|
|
593
|
+
*/
|
|
594
|
+
function requireName(name, names, subject) {
|
|
595
|
+
if (typeof name != "string" || !declarationNamePattern.test(name) || names.has(name))
|
|
596
|
+
invalid(`Duplicate or invalid ${subject} name.`);
|
|
597
|
+
names.add(name);
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* Requires an ordinary object.
|
|
601
|
+
* @param {unknown} value - Candidate value.
|
|
602
|
+
* @param {string} subject - Diagnostic subject.
|
|
603
|
+
* @returns {asserts value is Record<string, unknown>} Asserts an ordinary object.
|
|
604
|
+
*/
|
|
605
|
+
function requirePlain(value, subject) {
|
|
606
|
+
if (!value || typeof value != "object" || Array.isArray(value) || Object.getPrototypeOf(value) != Object.prototype)
|
|
607
|
+
invalid(`Invalid ${subject} object.`);
|
|
608
|
+
}
|
|
609
|
+
/**
|
|
610
|
+
* Requires one exact field set.
|
|
611
|
+
* @param {Record<string, unknown>} value - Candidate object.
|
|
612
|
+
* @param {string[]} keys - Required keys.
|
|
613
|
+
* @param {string} subject - Diagnostic subject.
|
|
614
|
+
* @returns {void}
|
|
615
|
+
*/
|
|
616
|
+
function requireKeys(value, keys, subject) {
|
|
617
|
+
if (Object.keys(value).sort().join(",") != [...keys].sort().join(","))
|
|
618
|
+
invalid(`Invalid ${subject} fields.`);
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Checks an ordered dense array.
|
|
622
|
+
* @param {unknown} value - Candidate array.
|
|
623
|
+
* @returns {value is unknown[]} Whether the value is dense.
|
|
624
|
+
*/
|
|
625
|
+
function dense(value) {
|
|
626
|
+
return Array.isArray(value) && value.every((_item, index) => Object.hasOwn(value, index));
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Recursively freezes a detached authority graph.
|
|
630
|
+
* @template {object} Value
|
|
631
|
+
* @param {Value} value - Object to freeze.
|
|
632
|
+
* @returns {Readonly<Value>} Frozen object.
|
|
633
|
+
*/
|
|
634
|
+
function deepFreeze(value) {
|
|
635
|
+
for (const child of Object.values(value)) {
|
|
636
|
+
if (child && typeof child == "object" && !Object.isFrozen(child))
|
|
637
|
+
deepFreeze(child);
|
|
638
|
+
}
|
|
639
|
+
return Object.freeze(value);
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Raises one stable authority diagnostic.
|
|
643
|
+
* @param {string} message - Diagnostic message.
|
|
644
|
+
* @returns {never} Always throws.
|
|
645
|
+
*/
|
|
646
|
+
function invalid(message) {
|
|
647
|
+
throw new SemantifoldDiagnostic({ code: "INVALID_CAPABILITY_AUTHORITY", language: "capability", message });
|
|
648
|
+
}
|
|
649
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FwYWJpbGl0aWVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlbWFudGljL2NhcGFiaWxpdGllcy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEQsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sYUFBYSxDQUFBO0FBRW5ELE1BQU0sZUFBZSxHQUFHLGdDQUFnQyxDQUFBO0FBQ3hELE1BQU0sa0JBQWtCLEdBQUcscUJBQXFCLENBQUE7QUFDaEQsTUFBTSxzQkFBc0IsR0FBRywyQkFBMkIsQ0FBQTtBQUMxRCxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtBQUM3RCxNQUFNLGtCQUFrQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFDeEM7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDM0MsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsd0JBQXdCLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsSUFBSSxFQUFFLE1BQU0sRUFBQyxDQUFDO1FBQ3JHLElBQUksRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ2hILFVBQVUsRUFBRSxTQUFTLEVBQUMsQ0FBQztJQUN6QixNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxN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LE9BQU87SUFDdEIsTUFBTSxJQUFJLHFCQUFxQixDQUFDLEVBQUMsSUFBSSxFQUFFLDhCQUE4QixFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQTtBQUMxRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7U2VtYW50aWZvbGREaWFnbm9zdGljfSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge3BhcnNlU3RkbGliVmVyc2lvblJhbmdlfSBmcm9tIFwiLi9zdGRsaWIuanNcIlxuXG5jb25zdCBhdXRob3JpdHlTY2hlbWEgPSBcIlNlbWFudGlmb2xkQ2FwYWJpbGl0eUF1dGhvcml0eVwiXG5jb25zdCBhdXRob3JpdHlJZFBhdHRlcm4gPSAvXlthLXpdW2EtejAtOS4tXSokL3VcbmNvbnN0IGRlY2xhcmF0aW9uTmFtZVBhdHRlcm4gPSAvXltBLVphLXpfXVtBLVphLXowLTlfXSokL3VcbmNvbnN0IHNjYWxhck5hbWVzID0gbmV3IFNldChbXCJib29sZWFuXCIsIFwiaW50ZWdlclwiLCBcInN0cmluZ1wiXSlcbmNvbnN0IGNyZWF0ZWRBdXRob3JpdGllcyA9IG5ldyBXZWFrU2V0KClcbi8qKlxuICogQHR5cGVkZWYgQ2FwYWJpbGl0eUF1dGhvcml0eVYyU3RhdGVcbiAqIEBwcm9wZXJ0eSB7e2NhbmRpZGF0ZTogaW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DYXBhYmlsaXR5RGVjbGFyYXRpb25JbnB1dCwgY2FwYWJpbGl0eUlkOiBzdHJpbmcsIGZhaWx1cmVzOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVmZmVjdEZhaWx1cmVEZWNsYXJhdGlvbltdLCByZXNvdXJjZXM6IGltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbltdfVtdfSBjYXBhYmlsaXRpZXMgLSBQcmVwYXJlZCBjYXBhYmlsaXR5IGRlY2xhcmF0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPn0gZmFpbHVyZU5hbWVzIC0gTW9kdWxlLWxvY2FsIGZhaWx1cmVzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGlkZW50aXR5IC0gQ2Fub25pY2FsIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBtb2R1bGVJbmRleCAtIFN0YWJsZSBtb2R1bGUgcG9zaXRpb24uXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD59IHJlc291cmNlTmFtZXMgLSBNb2R1bGUtbG9jYWwgcmVzb3VyY2VzLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGNvbnRyYWN0VmVyc2lvbiAtIENhbm9uaWNhbCBjb250cmFjdCByYW5nZS5cbiAqL1xuY29uc3QgdGFzazAzNFByb2JlT3BlcmF0aW9ucyA9IE9iamVjdC5mcmVlemUoW1xuICBPYmplY3QuZnJlZXplKHtmYWlsdXJlczogT2JqZWN0LmZyZWV6ZShbXCJjYXBhYmlsaXR5OjAvZmFpbHVyZTowXCJdKSwgZmxvdzogT2JqZWN0LmZyZWV6ZSh7a2luZDogXCJub25lXCJ9KSxcbiAgICBuYW1lOiBcInByb2JlRWZmZWN0XCIsIHBhcmFtZXRlcnM6IE9iamVjdC5mcmVlemUoW1tcImxhYmVsXCIsIFwic3RyaW5nXCJdLCBbXCJ2YWx1ZVwiLCBcImludGVnZXJcIl0sIFtcImZhaWxcIiwgXCJib29sZWFuXCJdXSksXG4gICAgcmV0dXJuVHlwZTogXCJpbnRlZ2VyXCJ9KSxcbiAgT2JqZWN0LmZyZWV6ZSh7ZmFpbHVyZXM6IE9iamVjdC5mcmVlemUoW1wiY2FwYWJpbGl0eTowL2ZhaWx1cmU6MVwiXSksXG4gICAgZmxvdzogT2JqZWN0LmZyZWV6ZSh7a2luZDogXCJhY3F1aXJlXCIsIHJlc291cmNlSWQ6IFwiY2FwYWJpbGl0eTowL3Jlc291cmNlOjBcIn0pLCBuYW1lOiBcInByb2JlQWNxdWlyZVwiLFxuICAgIHBhcmFtZXRlcnM6IE9iamVjdC5mcmVlemUoW1tcImZhaWxcIiwgXCJib29sZWFuXCJdXSksIHJldHVyblR5cGU6IFwicmVzb3VyY2VcIn0pLFxuICBPYmplY3QuZnJlZXplKHtmYWlsdXJlczogT2JqZWN0LmZyZWV6ZShbXCJjYXBhYmlsaXR5OjAvZmFpbHVyZToyXCIsIFwiY2FwYWJpbGl0eTowL2ZhaWx1cmU6NFwiXSksXG4gICAgZmxvdzogT2JqZWN0LmZyZWV6ZSh7a2luZDogXCJib3Jyb3dcIiwgcGFyYW1ldGVySW5kZXg6IDAsIHRlcm1pbmFsRmFpbHVyZUlkOiBcImNhcGFiaWxpdHk6MC9mYWlsdXJlOjRcIn0pLCBuYW1lOiBcInByb2JlUmVhZFwiLFxuICAgIHBhcmFtZXRlcnM6IE9iamVjdC5mcmVlemUoW1tcInJlc291cmNlXCIsIFwicmVzb3VyY2VcIl0sIFtcImZhaWxcIiwgXCJib29sZWFuXCJdXSksIHJldHVyblR5cGU6IFwib3B0aW9uYWw6c3RyaW5nXCJ9KSxcbiAgT2JqZWN0LmZyZWV6ZSh7ZmFpbHVyZXM6IE9iamVjdC5mcmVlemUoW1wiY2FwYWJpbGl0eTowL2ZhaWx1cmU6M1wiLCBcImNhcGFiaWxpdHk6MC9mYWlsdXJlOjRcIl0pLFxuICAgIGZsb3c6IE9iamVjdC5mcmVlemUoe2tpbmQ6IFwiY2xvc2VcIiwgcGFyYW1ldGVySW5kZXg6IDAsIHRlcm1pbmFsRmFpbHVyZUlkOiBcImNhcGFiaWxpdHk6MC9mYWlsdXJlOjRcIn0pLCBuYW1lOiBcInByb2JlQ2xvc2VcIixcbiAgICBwYXJhbWV0ZXJzOiBPYmplY3QuZnJlZXplKFtbXCJyZXNvdXJjZVwiLCBcInJlc291cmNlXCJdLCBbXCJmYWlsXCIsIFwiYm9vbGVhblwiXV0pLCByZXR1cm5UeXBlOiBcInZvaWRcIn0pLFxuICBPYmplY3QuZnJlZXplKHtmYWlsdXJlczogT2JqZWN0LmZyZWV6ZShbXSksIGZsb3c6IE9iamVjdC5mcmVlemUoe2tpbmQ6IFwibm9uZVwifSksIG5hbWU6IFwicHJvYmVUcmFjZVwiLFxuICAgIHBhcmFtZXRlcnM6IE9iamVjdC5mcmVlemUoW10pLCByZXR1cm5UeXBlOiBcInN0cmluZ1wifSlcbl0pXG5cbi8qKlxuICogQ3JlYXRlcyBhbiBpbW11dGFibGUsIGRldGFjaGVkIGNvbXBpbGVyLWF1dGhvcml0eSBkZXNjcmlwdG9yLlxuICogQHBhcmFtIHt1bmtub3dufSBpbnB1dCAtIFVudHJ1c3RlZCBhdXRob3JpdHkgaW5wdXQuXG4gKiBAcmV0dXJucyB7UmVhZG9ubHk8aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DYXBhYmlsaXR5QXV0aG9yaXR5Pn0gTm9ybWFsaXplZCBhdXRob3JpdHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVDYXBhYmlsaXR5QXV0aG9yaXR5KGlucHV0KSB7XG4gIHRyeSB7XG4gICAgaWYgKGNyZWF0ZWRBdXRob3JpdGllcy5oYXMoLyoqIEB0eXBlIHtvYmplY3R9ICovIChpbnB1dCkpKSByZXR1cm4gLyoqIEB0eXBlIHtSZWFkb25seTxpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNhcGFiaWxpdHlBdXRob3JpdHk+fSAqLyAoaW5wdXQpXG4gICAgcmVxdWlyZVBsYWluKGlucHV0LCBcImF1dGhvcml0eVwiKVxuICAgIGNvbnN0IGF1dGhvcml0eUlucHV0ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkNhcGFiaWxpdHlBdXRob3JpdHlJbnB1dH0gKi8gKGlucHV0KVxuXG4gICAgaWYgKGF1dGhvcml0eUlucHV0LnNjaGVtYVZlcnNpb24gPT0gMikgcmV0dXJuIGNyZWF0ZUNhcGFiaWxpdHlBdXRob3JpdHlWMihhdXRob3JpdHlJbnB1dClcbiAgICBjb25zdCBoYXNDb250cmFjdFZlcnNpb24gPSBPYmplY3QuaGFzT3duKGF1dGhvcml0eUlucHV0LCBcImNvbnRyYWN0VmVyc2lvblwiKVxuXG4gICAgcmVxdWlyZUtleXMoYXV0aG9yaXR5SW5wdXQsIGhhc0NvbnRyYWN0VmVyc2lvblxuICAgICAgPyBbXCJjYXBhYmlsaXRpZXNcIiwgXCJjb250cmFjdFZlcnNpb25cIiwgXCJpZFwiLCBcInNjaGVtYVwiLCBcInNjaGVtYVZlcnNpb25cIl1cbiAgICAgIDogW1wiY2FwYWJpbGl0aWVzXCIsIFwiaWRcIiwgXCJzY2hlbWFcIiwgXCJzY2hlbWFWZXJzaW9uXCJdLCBcImF1dGhvcml0eVwiKVxuICAgIGlmIChoYXNDb250cmFjdFZlcnNpb24gJiYgcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UoYXV0aG9yaXR5SW5wdXQuY29udHJhY3RWZXJzaW9uKSA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICAgIGNvZGU6IFwiU1RETElCX1ZFUlNJT05fTUFMRk9STUVEXCIsXG4gICAgICAgIGxhbmd1YWdlOiBcImNhcGFiaWxpdHlcIixcbiAgICAgICAgbWVzc2FnZTogXCJDYXBhYmlsaXR5IGF1dGhvcml0eSBjb250cmFjdFZlcnNpb24gaXMgbm90IGEgY2Fub25pY2FsIHN0ZGxpYiB2ZXJzaW9uIHJhbmdlLlwiXG4gICAgICB9KVxuICAgIH1cbiAgICBpZiAoYXV0aG9yaXR5SW5wdXQuc2NoZW1hICE9IGF1dGhvcml0eVNjaGVtYSB8fCBhdXRob3JpdHlJbnB1dC5zY2hlbWFWZXJzaW9uICE9IDEgfHwgdHlwZW9mIGF1dGhvcml0eUlucHV0LmlkICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICFhdXRob3JpdHlJZFBhdHRlcm4udGVzdChhdXRob3JpdHlJbnB1dC5pZCkgfHwgIWRlbnNlKGF1dGhvcml0eUlucHV0LmNhcGFiaWxpdGllcykpIGludmFsaWQoXCJBdXRob3JpdHkgc2NoZW1hLCB2ZXJzaW9uLCBpZGVudGl0eSwgb3IgY2FwYWJpbGl0eSBsaXN0IGlzIGludmFsaWQuXCIpXG5cbiAgICBjb25zdCBjYXBhYmlsaXR5TmFtZXMgPSBuZXcgU2V0KClcbiAgICBjb25zdCBhdXRob3JpdHlSZXNvdXJjZU5hbWVzID0gbmV3IFNldCgpXG4gICAgY29uc3QgYXV0aG9yaXR5RmFpbHVyZU5hbWVzID0gbmV3IFNldCgpXG4gICAgY29uc3QgYXV0aG9yaXR5T3BlcmF0aW9uTmFtZXMgPSBuZXcgU2V0KClcbiAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBhdXRob3JpdHlJbnB1dC5jYXBhYmlsaXRpZXMubWFwKChjYW5kaWRhdGUsIGNhcGFiaWxpdHlJbmRleCkgPT4ge1xuICAgICAgcmVxdWlyZVBsYWluKGNhbmRpZGF0ZSwgYGNhcGFiaWxpdHkgJHtjYXBhYmlsaXR5SW5kZXh9YClcbiAgICAgIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wiZmFpbHVyZXNcIiwgXCJuYW1lXCIsIFwib3BlcmF0aW9uc1wiLCBcInJlc291cmNlc1wiXSwgYGNhcGFiaWxpdHkgJHtjYXBhYmlsaXR5SW5kZXh9YClcbiAgICAgIHJlcXVpcmVOYW1lKGNhbmRpZGF0ZS5uYW1lLCBjYXBhYmlsaXR5TmFtZXMsIFwiY2FwYWJpbGl0eVwiKVxuICAgICAgaWYgKCFkZW5zZShjYW5kaWRhdGUucmVzb3VyY2VzKSB8fCAhZGVuc2UoY2FuZGlkYXRlLmZhaWx1cmVzKSB8fCAhZGVuc2UoY2FuZGlkYXRlLm9wZXJhdGlvbnMpKSB7XG4gICAgICAgIGludmFsaWQoYENhcGFiaWxpdHkgJyR7Y2FuZGlkYXRlLm5hbWV9JyByZXF1aXJlcyBvcmRlcmVkIHJlc291cmNlLCBmYWlsdXJlLCBhbmQgb3BlcmF0aW9uIGFycmF5cy5gKVxuICAgICAgfVxuICAgICAgY29uc3QgY2FwYWJpbGl0eUlkID0gYGNhcGFiaWxpdHk6JHtjYXBhYmlsaXR5SW5kZXh9YFxuICAgICAgY29uc3QgcmVzb3VyY2VOYW1lcyA9IG5ldyBNYXAoKVxuICAgICAgY29uc3QgcmVzb3VyY2VzID0gY2FuZGlkYXRlLnJlc291cmNlcy5tYXAoKHJlc291cmNlLCByZXNvdXJjZUluZGV4KSA9PiB7XG4gICAgICAgIHJlcXVpcmVOYW1lZChyZXNvdXJjZSwgcmVzb3VyY2VOYW1lcywgXCJyZXNvdXJjZVwiKVxuICAgICAgICByZXF1aXJlTmFtZShyZXNvdXJjZS5uYW1lLCBhdXRob3JpdHlSZXNvdXJjZU5hbWVzLCBcImF1dGhvcml0eSByZXNvdXJjZVwiKVxuICAgICAgICBjb25zdCBpZCA9IGAke2NhcGFiaWxpdHlJZH0vcmVzb3VyY2U6JHtyZXNvdXJjZUluZGV4fWBcbiAgICAgICAgcmVzb3VyY2VOYW1lcy5zZXQocmVzb3VyY2UubmFtZSwgaWQpXG4gICAgICAgIHJldHVybiB7aWQsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb25cIiksIG5hbWU6IHJlc291cmNlLm5hbWV9XG4gICAgICB9KVxuICAgICAgY29uc3QgZmFpbHVyZU5hbWVzID0gbmV3IE1hcCgpXG4gICAgICBjb25zdCBmYWlsdXJlcyA9IGNhbmRpZGF0ZS5mYWlsdXJlcy5tYXAoKGZhaWx1cmUsIGZhaWx1cmVJbmRleCkgPT4ge1xuICAgICAgICByZXF1aXJlTmFtZWQoZmFpbHVyZSwgZmFpbHVyZU5hbWVzLCBcImZhaWx1cmVcIilcbiAgICAgICAgcmVxdWlyZU5hbWUoZmFpbHVyZS5uYW1lLCBhdXRob3JpdHlGYWlsdXJlTmFtZXMsIFwiYXV0aG9yaXR5IGZhaWx1cmVcIilcbiAgICAgICAgY29uc3QgaWQgPSBgJHtjYXBhYmlsaXR5SWR9L2ZhaWx1cmU6JHtmYWlsdXJlSW5kZXh9YFxuICAgICAgICBmYWlsdXJlTmFtZXMuc2V0KGZhaWx1cmUubmFtZSwgaWQpXG4gICAgICAgIHJldHVybiB7aWQsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVmZmVjdEZhaWx1cmVEZWNsYXJhdGlvblwiKSwgbmFtZTogZmFpbHVyZS5uYW1lfVxuICAgICAgfSlcbiAgICAgIGNvbnN0IG9wZXJhdGlvbk5hbWVzID0gbmV3IFNldCgpXG4gICAgICBjb25zdCBvcGVyYXRpb25zID0gY2FuZGlkYXRlLm9wZXJhdGlvbnMubWFwKChvcGVyYXRpb24sIG9wZXJhdGlvbkluZGV4KSA9PiB7XG4gICAgICAgIHJlcXVpcmVQbGFpbihvcGVyYXRpb24sIGBvcGVyYXRpb24gJHtvcGVyYXRpb25JbmRleH1gKVxuICAgICAgICByZXF1aXJlS2V5cyhvcGVyYXRpb24sIFtcImVmZmVjdHNcIiwgXCJmYWlsdXJlc1wiLCBcIm5hbWVcIiwgXCJwYXJhbWV0ZXJzXCIsIFwicmVzb3VyY2VGbG93XCIsIFwicmV0dXJuVHlwZVwiXSwgYG9wZXJhdGlvbiAke29wZXJhdGlvbkluZGV4fWApXG4gICAgICAgIHJlcXVpcmVOYW1lKG9wZXJhdGlvbi5uYW1lLCBvcGVyYXRpb25OYW1lcywgXCJvcGVyYXRpb25cIilcbiAgICAgICAgcmVxdWlyZU5hbWUob3BlcmF0aW9uLm5hbWUsIGF1dGhvcml0eU9wZXJhdGlvbk5hbWVzLCBcImF1dGhvcml0eSBvcGVyYXRpb25cIilcbiAgICAgICAgaWYgKCFkZW5zZShvcGVyYXRpb24ucGFyYW1ldGVycykgfHwgIWRlbnNlKG9wZXJhdGlvbi5mYWlsdXJlcykgfHwgIWRlbnNlKG9wZXJhdGlvbi5lZmZlY3RzKSB8fFxuICAgICAgICAgIG9wZXJhdGlvbi5lZmZlY3RzLmxlbmd0aCAhPSAxIHx8IG9wZXJhdGlvbi5lZmZlY3RzWzBdICE9IFwiaG9zdFwiKSBpbnZhbGlkKGBPcGVyYXRpb24gJyR7b3BlcmF0aW9uLm5hbWV9JyBoYXMgYW4gaW52YWxpZCBlZmZlY3QgZGVjbGFyYXRpb24uYClcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyTmFtZXMgPSBuZXcgU2V0KClcbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IG9wZXJhdGlvbi5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyLCBwYXJhbWV0ZXJJbmRleCkgPT4ge1xuICAgICAgICAgIHJlcXVpcmVQbGFpbihwYXJhbWV0ZXIsIGBwYXJhbWV0ZXIgJHtwYXJhbWV0ZXJJbmRleH1gKVxuICAgICAgICAgIHJlcXVpcmVLZXlzKHBhcmFtZXRlciwgW1wibmFtZVwiLCBcInR5cGVcIl0sIGBwYXJhbWV0ZXIgJHtwYXJhbWV0ZXJJbmRleH1gKVxuICAgICAgICAgIHJlcXVpcmVOYW1lKHBhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXJOYW1lcywgXCJwYXJhbWV0ZXJcIilcbiAgICAgICAgICByZXR1cm4ge25hbWU6IHBhcmFtZXRlci5uYW1lLCB0eXBlOiBub3JtYWxpemVWYWx1ZVR5cGUocGFyYW1ldGVyLnR5cGUsIHJlc291cmNlTmFtZXMpfVxuICAgICAgICB9KVxuICAgICAgICBjb25zdCByZXR1cm5UeXBlID0gb3BlcmF0aW9uLnJldHVyblR5cGUgPT0gXCJ2b2lkXCIgPyB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHlwZVJlZmVyZW5jZVwiKSwgbmFtZTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwidm9pZFwiKX0gOlxuICAgICAgICAgIG5vcm1hbGl6ZVZhbHVlVHlwZShvcGVyYXRpb24ucmV0dXJuVHlwZSwgcmVzb3VyY2VOYW1lcylcbiAgICAgICAgY29uc3QgZmFpbHVyZUlkcyA9IG9wZXJhdGlvbi5mYWlsdXJlcy5tYXAoKG5hbWUpID0+IHtcbiAgICAgICAgICBpZiAodHlwZW9mIG5hbWUgIT0gXCJzdHJpbmdcIiB8fCAhZmFpbHVyZU5hbWVzLmhhcyhuYW1lKSkgaW52YWxpZChgT3BlcmF0aW9uICcke29wZXJhdGlvbi5uYW1lfScgbmFtZXMgYW4gdW5kZWNsYXJlZCBmYWlsdXJlICcke1N0cmluZyhuYW1lKX0nLmApXG4gICAgICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmFpbHVyZU5hbWVzLmdldChuYW1lKSlcbiAgICAgICAgfSlcbiAgICAgICAgaWYgKG5ldyBTZXQoZmFpbHVyZUlkcykuc2l6ZSAhPSBmYWlsdXJlSWRzLmxlbmd0aCkgaW52YWxpZChgT3BlcmF0aW9uICcke29wZXJhdGlvbi5uYW1lfScgcmVwZWF0cyBhIGRlY2xhcmVkIGZhaWx1cmUuYClcbiAgICAgICAgY29uc3QgcmVzb3VyY2VGbG93ID0gbm9ybWFsaXplUmVzb3VyY2VGbG93KG9wZXJhdGlvbi5yZXNvdXJjZUZsb3csIHJlc291cmNlcywgcmVzb3VyY2VOYW1lcywgZmFpbHVyZU5hbWVzLCBwYXJhbWV0ZXJzKVxuXG4gICAgICAgIHZhbGlkYXRlUmVzb3VyY2VPcGVyYXRpb24ob3BlcmF0aW9uLm5hbWUsIHBhcmFtZXRlcnMsIHJldHVyblR5cGUsIGZhaWx1cmVJZHMsIHJlc291cmNlRmxvdylcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVmZmVjdHM6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChbXCJob3N0XCJdKSxcbiAgICAgICAgICBmYWlsdXJlSWRzLFxuICAgICAgICAgIGlkOiBgJHtjYXBhYmlsaXR5SWR9L29wZXJhdGlvbjoke29wZXJhdGlvbkluZGV4fWAsXG4gICAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRWZmZWN0T3BlcmF0aW9uRGVjbGFyYXRpb25cIiksXG4gICAgICAgICAgbmFtZTogb3BlcmF0aW9uLm5hbWUsXG4gICAgICAgICAgcGFyYW1ldGVycyxcbiAgICAgICAgICByZXNvdXJjZUZsb3csXG4gICAgICAgICAgcmV0dXJuVHlwZVxuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBhdXRob3JpdHlJZDogYXV0aG9yaXR5SW5wdXQuaWQsXG4gICAgICAgIGZhaWx1cmVzLFxuICAgICAgICBpZDogY2FwYWJpbGl0eUlkLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFZmZlY3RDYXBhYmlsaXR5RGVjbGFyYXRpb25cIiksXG4gICAgICAgIG5hbWU6IGNhbmRpZGF0ZS5uYW1lLFxuICAgICAgICBvcGVyYXRpb25zLFxuICAgICAgICByZXNvdXJjZXNcbiAgICAgIH1cbiAgICB9KVxuICAgIGNvbnN0IHJlc3VsdCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5DYXBhYmlsaXR5QXV0aG9yaXR5fSAqLyAoe1xuICAgICAgY2FwYWJpbGl0aWVzLFxuICAgICAgaWQ6IGF1dGhvcml0eUlucHV0LmlkLFxuICAgICAgc2NoZW1hOiBhdXRob3JpdHlTY2hlbWEsXG4gICAgICBzY2hlbWFWZXJzaW9uOiAxLFxuICAgICAgLi4uKGhhc0NvbnRyYWN0VmVyc2lvbiA/IHtjb250cmFjdFZlcnNpb246IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoYXV0aG9yaXR5SW5wdXQuY29udHJhY3RWZXJzaW9uKX0gOiB7fSlcbiAgICB9KVxuXG4gICAgZGVlcEZyZWV6ZShyZXN1bHQpXG4gICAgY3JlYXRlZEF1dGhvcml0aWVzLmFkZChyZXN1bHQpXG4gICAgcmV0dXJuIHJlc3VsdFxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlbWFudGlmb2xkRGlhZ25vc3RpYykgdGhyb3cgZXJyb3JcbiAgICByZXR1cm4gaW52YWxpZChcIkF1dGhvcml0eSBwYXlsb2FkIGlzIG1hbGZvcm1lZC5cIilcbiAgfVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSBzdHJpY3QgbXVsdGktbW9kdWxlIHNjaGVtYS12MiBhdXRob3JpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eUlucHV0fSBhdXRob3JpdHlJbnB1dCAtIFZhbGlkYXRlZCBvdXRlciBvYmplY3QgY2FuZGlkYXRlLlxuICogQHJldHVybnMge1JlYWRvbmx5PGltcG9ydChcIi4vdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eT59IE5vcm1hbGl6ZWQgYXV0aG9yaXR5LlxuICovXG5mdW5jdGlvbiBjcmVhdGVDYXBhYmlsaXR5QXV0aG9yaXR5VjIoYXV0aG9yaXR5SW5wdXQpIHtcbiAgcmVxdWlyZUtleXMoLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKGF1dGhvcml0eUlucHV0KSwgW1wiaWRcIiwgXCJtb2R1bGVzXCIsIFwic2NoZW1hXCIsIFwic2NoZW1hVmVyc2lvblwiXSwgXCJhdXRob3JpdHlcIilcbiAgaWYgKGF1dGhvcml0eUlucHV0LnNjaGVtYSAhPSBhdXRob3JpdHlTY2hlbWEgfHwgYXV0aG9yaXR5SW5wdXQuc2NoZW1hVmVyc2lvbiAhPSAyIHx8XG4gICAgdHlwZW9mIGF1dGhvcml0eUlucHV0LmlkICE9IFwic3RyaW5nXCIgfHwgIWF1dGhvcml0eUlkUGF0dGVybi50ZXN0KGF1dGhvcml0eUlucHV0LmlkKSB8fCAhZGVuc2UoYXV0aG9yaXR5SW5wdXQubW9kdWxlcykpIHtcbiAgICBpbnZhbGlkKFwiQXV0aG9yaXR5IHNjaGVtYSwgdmVyc2lvbiwgaWRlbnRpdHksIG9yIG1vZHVsZSBsaXN0IGlzIGludmFsaWQuXCIpXG4gIH1cbiAgY29uc3QgaWRlbnRpdGllcyA9IG5ldyBTZXQoKVxuICBjb25zdCBtb2R1bGVJbnB1dHMgPSBhdXRob3JpdHlJbnB1dC5tb2R1bGVzLm1hcCgoY2FuZGlkYXRlLCBtb2R1bGVJbmRleCkgPT4ge1xuICAgIHJlcXVpcmVQbGFpbihjYW5kaWRhdGUsIGBtb2R1bGUgJHttb2R1bGVJbmRleH1gKVxuICAgIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wiY2FwYWJpbGl0aWVzXCIsIFwiY29udHJhY3RWZXJzaW9uXCIsIFwiaWRlbnRpdHlcIl0sIGBtb2R1bGUgJHttb2R1bGVJbmRleH1gKVxuICAgIGlmICh0eXBlb2YgY2FuZGlkYXRlLmlkZW50aXR5ICE9IFwic3RyaW5nXCIgfHwgIWF1dGhvcml0eUlkUGF0dGVybi50ZXN0KGNhbmRpZGF0ZS5pZGVudGl0eSkgfHwgaWRlbnRpdGllcy5oYXMoY2FuZGlkYXRlLmlkZW50aXR5KSB8fFxuICAgICAgcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UoY2FuZGlkYXRlLmNvbnRyYWN0VmVyc2lvbikgPT09IG51bGwgfHwgIWRlbnNlKGNhbmRpZGF0ZS5jYXBhYmlsaXRpZXMpKSB7XG4gICAgICBpbnZhbGlkKGBBdXRob3JpdHkgbW9kdWxlICR7bW9kdWxlSW5kZXh9IGlzIGludmFsaWQgb3IgZHVwbGljYXRlLmApXG4gICAgfVxuICAgIGlkZW50aXRpZXMuYWRkKGNhbmRpZGF0ZS5pZGVudGl0eSlcbiAgICByZXR1cm4gY2FuZGlkYXRlXG4gIH0pXG4gIGNvbnN0IHN0YXRlcyA9IG1vZHVsZUlucHV0cy5tYXAoKG1vZHVsZUlucHV0LCBtb2R1bGVJbmRleCkgPT4ge1xuICAgIGNvbnN0IHJlc291cmNlTmFtZXMgPSBuZXcgTWFwKClcbiAgICBjb25zdCBmYWlsdXJlTmFtZXMgPSBuZXcgTWFwKClcbiAgICBjb25zdCBjYXBhYmlsaXR5TmFtZXMgPSBuZXcgU2V0KClcbiAgICBjb25zdCBjYXBhYmlsaXRpZXMgPSBtb2R1bGVJbnB1dC5jYXBhYmlsaXRpZXMubWFwKChjYW5kaWRhdGUsIGNhcGFiaWxpdHlJbmRleCkgPT4ge1xuICAgICAgcmVxdWlyZVBsYWluKGNhbmRpZGF0ZSwgYG1vZHVsZSAke21vZHVsZUluZGV4fSBjYXBhYmlsaXR5ICR7Y2FwYWJpbGl0eUluZGV4fWApXG4gICAgICByZXF1aXJlS2V5cyhjYW5kaWRhdGUsIFtcImZhaWx1cmVzXCIsIFwibmFtZVwiLCBcIm9wZXJhdGlvbnNcIiwgXCJyZXNvdXJjZXNcIl0sIGBtb2R1bGUgJHttb2R1bGVJbmRleH0gY2FwYWJpbGl0eSAke2NhcGFiaWxpdHlJbmRleH1gKVxuICAgICAgcmVxdWlyZU5hbWUoY2FuZGlkYXRlLm5hbWUsIGNhcGFiaWxpdHlOYW1lcywgXCJjYXBhYmlsaXR5XCIpXG4gICAgICBpZiAoIWRlbnNlKGNhbmRpZGF0ZS5yZXNvdXJjZXMpIHx8ICFkZW5zZShjYW5kaWRhdGUuZmFpbHVyZXMpIHx8ICFkZW5zZShjYW5kaWRhdGUub3BlcmF0aW9ucykpIHtcbiAgICAgICAgaW52YWxpZChgQ2FwYWJpbGl0eSAnJHtjYW5kaWRhdGUubmFtZX0nIHJlcXVpcmVzIG9yZGVyZWQgcmVzb3VyY2UsIGZhaWx1cmUsIGFuZCBvcGVyYXRpb24gYXJyYXlzLmApXG4gICAgICB9XG4gICAgICBjb25zdCBjYXBhYmlsaXR5SWQgPSBgbW9kdWxlOiR7bW9kdWxlSW5kZXh9L2NhcGFiaWxpdHk6JHtjYXBhYmlsaXR5SW5kZXh9YFxuICAgICAgY29uc3QgcmVzb3VyY2VzID0gY2FuZGlkYXRlLnJlc291cmNlcy5tYXAoKHJlc291cmNlLCByZXNvdXJjZUluZGV4KSA9PiB7XG4gICAgICAgIHJlcXVpcmVOYW1lZChyZXNvdXJjZSwgcmVzb3VyY2VOYW1lcywgXCJtb2R1bGUgcmVzb3VyY2VcIilcbiAgICAgICAgY29uc3QgaWQgPSBgJHtjYXBhYmlsaXR5SWR9L3Jlc291cmNlOiR7cmVzb3VyY2VJbmRleH1gXG5cbiAgICAgICAgcmVzb3VyY2VOYW1lcy5zZXQocmVzb3VyY2UubmFtZSwgaWQpXG4gICAgICAgIHJldHVybiB7aWQsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb25cIiksIG5hbWU6IHJlc291cmNlLm5hbWV9XG4gICAgICB9KVxuICAgICAgY29uc3QgZmFpbHVyZXMgPSBjYW5kaWRhdGUuZmFpbHVyZXMubWFwKChmYWlsdXJlLCBmYWlsdXJlSW5kZXgpID0+IHtcbiAgICAgICAgcmVxdWlyZU5hbWVkKGZhaWx1cmUsIGZhaWx1cmVOYW1lcywgXCJtb2R1bGUgZmFpbHVyZVwiKVxuICAgICAgICBjb25zdCBpZCA9IGAke2NhcGFiaWxpdHlJZH0vZmFpbHVyZToke2ZhaWx1cmVJbmRleH1gXG5cbiAgICAgICAgZmFpbHVyZU5hbWVzLnNldChmYWlsdXJlLm5hbWUsIGlkKVxuICAgICAgICByZXR1cm4ge2lkLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFZmZlY3RGYWlsdXJlRGVjbGFyYXRpb25cIiksIG5hbWU6IGZhaWx1cmUubmFtZX1cbiAgICAgIH0pXG5cbiAgICAgIHJldHVybiB7Y2FuZGlkYXRlLCBjYXBhYmlsaXR5SWQsIGZhaWx1cmVzLCByZXNvdXJjZXN9XG4gICAgfSlcblxuICAgIHJldHVybiB7Y2FwYWJpbGl0aWVzLCBmYWlsdXJlTmFtZXMsIGlkZW50aXR5OiBtb2R1bGVJbnB1dC5pZGVudGl0eSwgbW9kdWxlSW5kZXgsIHJlc291cmNlTmFtZXMsXG4gICAgICBjb250cmFjdFZlcnNpb246IG1vZHVsZUlucHV0LmNvbnRyYWN0VmVyc2lvbn1cbiAgfSlcbiAgY29uc3Qgb3BlcmF0aW9uTmFtZXMgPSBuZXcgU2V0KClcbiAgY29uc3Qgbm9ybWFsaXplZE1vZHVsZXMgPSBzdGF0ZXMubWFwKChzdGF0ZSkgPT4ge1xuICAgIGNvbnN0IGNhcGFiaWxpdGllcyA9IHN0YXRlLmNhcGFiaWxpdGllcy5tYXAoKGNhcGFiaWxpdHlTdGF0ZSkgPT4ge1xuICAgICAgY29uc3QgbG9jYWxPcGVyYXRpb25OYW1lcyA9IG5ldyBTZXQoKVxuICAgICAgY29uc3Qgb3BlcmF0aW9ucyA9IGNhcGFiaWxpdHlTdGF0ZS5jYW5kaWRhdGUub3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbiwgb3BlcmF0aW9uSW5kZXgpID0+IHtcbiAgICAgICAgcmVxdWlyZVBsYWluKG9wZXJhdGlvbiwgYG1vZHVsZSAke3N0YXRlLm1vZHVsZUluZGV4fSBvcGVyYXRpb24gJHtvcGVyYXRpb25JbmRleH1gKVxuICAgICAgICByZXF1aXJlS2V5cyhvcGVyYXRpb24sIFtcImVmZmVjdHNcIiwgXCJmYWlsdXJlc1wiLCBcIm5hbWVcIiwgXCJwYXJhbWV0ZXJzXCIsIFwicmVzb3VyY2VGbG93XCIsIFwicmV0dXJuVHlwZVwiXSxcbiAgICAgICAgICBgbW9kdWxlICR7c3RhdGUubW9kdWxlSW5kZXh9IG9wZXJhdGlvbiAke29wZXJhdGlvbkluZGV4fWApXG4gICAgICAgIHJlcXVpcmVOYW1lKG9wZXJhdGlvbi5uYW1lLCBsb2NhbE9wZXJhdGlvbk5hbWVzLCBcIm9wZXJhdGlvblwiKVxuICAgICAgICBjb25zdCBxdWFsaWZpZWRPcGVyYXRpb25OYW1lID0gYCR7c3RhdGUuaWRlbnRpdHl9XFx1MDAwMCR7b3BlcmF0aW9uLm5hbWV9YFxuXG4gICAgICAgIGlmIChvcGVyYXRpb25OYW1lcy5oYXMocXVhbGlmaWVkT3BlcmF0aW9uTmFtZSkpIGludmFsaWQoYER1cGxpY2F0ZSBhdXRob3JpdHkgb3BlcmF0aW9uICcke29wZXJhdGlvbi5uYW1lfScuYClcbiAgICAgICAgb3BlcmF0aW9uTmFtZXMuYWRkKHF1YWxpZmllZE9wZXJhdGlvbk5hbWUpXG4gICAgICAgIGlmICghZGVuc2Uob3BlcmF0aW9uLnBhcmFtZXRlcnMpIHx8ICFkZW5zZShvcGVyYXRpb24uZmFpbHVyZXMpIHx8ICFkZW5zZShvcGVyYXRpb24uZWZmZWN0cykgfHxcbiAgICAgICAgICBvcGVyYXRpb24uZWZmZWN0cy5sZW5ndGggIT0gMSB8fCBvcGVyYXRpb24uZWZmZWN0c1swXSAhPSBcImhvc3RcIikge1xuICAgICAgICAgIGludmFsaWQoYE9wZXJhdGlvbiAnJHtvcGVyYXRpb24ubmFtZX0nIGhhcyBhbiBpbnZhbGlkIGVmZmVjdCBkZWNsYXJhdGlvbi5gKVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlck5hbWVzID0gbmV3IFNldCgpXG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBvcGVyYXRpb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlciwgcGFyYW1ldGVySW5kZXgpID0+IHtcbiAgICAgICAgICByZXF1aXJlUGxhaW4ocGFyYW1ldGVyLCBgcGFyYW1ldGVyICR7cGFyYW1ldGVySW5kZXh9YClcbiAgICAgICAgICByZXF1aXJlS2V5cyhwYXJhbWV0ZXIsIFtcIm5hbWVcIiwgXCJ0eXBlXCJdLCBgcGFyYW1ldGVyICR7cGFyYW1ldGVySW5kZXh9YClcbiAgICAgICAgICByZXF1aXJlTmFtZShwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyTmFtZXMsIFwicGFyYW1ldGVyXCIpXG4gICAgICAgICAgcmV0dXJuIHtuYW1lOiBwYXJhbWV0ZXIubmFtZSwgdHlwZTogbm9ybWFsaXplVjJWYWx1ZVR5cGUocGFyYW1ldGVyLnR5cGUsIHN0YXRlLCBzdGF0ZXMpfVxuICAgICAgICB9KVxuICAgICAgICBjb25zdCByZXR1cm5UeXBlID0gb3BlcmF0aW9uLnJldHVyblR5cGUgPT0gXCJ2b2lkXCJcbiAgICAgICAgICA/IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJUeXBlUmVmZXJlbmNlXCIpLCBuYW1lOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ2b2lkXCIpfVxuICAgICAgICAgIDogbm9ybWFsaXplVjJWYWx1ZVR5cGUob3BlcmF0aW9uLnJldHVyblR5cGUsIHN0YXRlLCBzdGF0ZXMpXG4gICAgICAgIGNvbnN0IGZhaWx1cmVJZHMgPSBvcGVyYXRpb24uZmFpbHVyZXMubWFwKChmYWlsdXJlKSA9PiByZXNvbHZlVjJEZWNsYXJhdGlvbihmYWlsdXJlLCBzdGF0ZSwgc3RhdGVzLCBcImZhaWx1cmVcIikpXG5cbiAgICAgICAgaWYgKG5ldyBTZXQoZmFpbHVyZUlkcykuc2l6ZSAhPSBmYWlsdXJlSWRzLmxlbmd0aCkgaW52YWxpZChgT3BlcmF0aW9uICcke29wZXJhdGlvbi5uYW1lfScgcmVwZWF0cyBhIGRlY2xhcmVkIGZhaWx1cmUuYClcbiAgICAgICAgY29uc3QgcmVzb3VyY2VGbG93ID0gbm9ybWFsaXplVjJSZXNvdXJjZUZsb3cob3BlcmF0aW9uLnJlc291cmNlRmxvdywgcGFyYW1ldGVycywgc3RhdGUsIHN0YXRlcylcblxuICAgICAgICB2YWxpZGF0ZVJlc291cmNlT3BlcmF0aW9uKG9wZXJhdGlvbi5uYW1lLCBwYXJhbWV0ZXJzLCByZXR1cm5UeXBlLCBmYWlsdXJlSWRzLCByZXNvdXJjZUZsb3cpXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZWZmZWN0czogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFtcImhvc3RcIl0pLFxuICAgICAgICAgIGZhaWx1cmVJZHMsXG4gICAgICAgICAgaWQ6IGAke2NhcGFiaWxpdHlTdGF0ZS5jYXBhYmlsaXR5SWR9L29wZXJhdGlvbjoke29wZXJhdGlvbkluZGV4fWAsXG4gICAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRWZmZWN0T3BlcmF0aW9uRGVjbGFyYXRpb25cIiksXG4gICAgICAgICAgbmFtZTogb3BlcmF0aW9uLm5hbWUsXG4gICAgICAgICAgcGFyYW1ldGVycyxcbiAgICAgICAgICByZXNvdXJjZUZsb3csXG4gICAgICAgICAgcmV0dXJuVHlwZVxuICAgICAgICB9XG4gICAgICB9KVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBhdXRob3JpdHlJZDogc3RhdGUuaWRlbnRpdHksXG4gICAgICAgIGZhaWx1cmVzOiBjYXBhYmlsaXR5U3RhdGUuZmFpbHVyZXMsXG4gICAgICAgIGlkOiBjYXBhYmlsaXR5U3RhdGUuY2FwYWJpbGl0eUlkLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFZmZlY3RDYXBhYmlsaXR5RGVjbGFyYXRpb25cIiksXG4gICAgICAgIG5hbWU6IGNhcGFiaWxpdHlTdGF0ZS5jYW5kaWRhdGUubmFtZSxcbiAgICAgICAgb3BlcmF0aW9ucyxcbiAgICAgICAgcmVzb3VyY2VzOiBjYXBhYmlsaXR5U3RhdGUucmVzb3VyY2VzXG4gICAgICB9XG4gICAgfSlcblxuICAgIHJldHVybiB7Y2FwYWJpbGl0aWVzLCBjb250cmFjdFZlcnNpb246IHN0YXRlLmNvbnRyYWN0VmVyc2lvbiwgaWRlbnRpdHk6IHN0YXRlLmlkZW50aXR5fVxuICB9KVxuICBjb25zdCByZXN1bHQgPSAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eX0gKi8gKHtcbiAgICBjYXBhYmlsaXRpZXM6IG5vcm1hbGl6ZWRNb2R1bGVzLmZsYXRNYXAoKHtjYXBhYmlsaXRpZXN9KSA9PiBjYXBhYmlsaXRpZXMpLFxuICAgIGlkOiBhdXRob3JpdHlJbnB1dC5pZCxcbiAgICBtb2R1bGVzOiBub3JtYWxpemVkTW9kdWxlcyxcbiAgICBzY2hlbWE6IGF1dGhvcml0eVNjaGVtYSxcbiAgICBzY2hlbWFWZXJzaW9uOiAyXG4gIH0pXG5cbiAgZGVlcEZyZWV6ZShyZXN1bHQpXG4gIGNyZWF0ZWRBdXRob3JpdGllcy5hZGQocmVzdWx0KVxuICByZXR1cm4gcmVzdWx0XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBvbmUgc2NoZW1hLXYyIHZhbHVlIHR5cGUuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSB0eXBlLlxuICogQHBhcmFtIHtDYXBhYmlsaXR5QXV0aG9yaXR5VjJTdGF0ZX0gc3RhdGUgLSBDdXJyZW50IG1vZHVsZSBzdGF0ZS5cbiAqIEBwYXJhbSB7Q2FwYWJpbGl0eUF1dGhvcml0eVYyU3RhdGVbXX0gc3RhdGVzIC0gQ29tcGxldGUgYXV0aG9yaXR5IHN0YXRlcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSBOb3JtYWxpemVkIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVYyVmFsdWVUeXBlKGNhbmRpZGF0ZSwgc3RhdGUsIHN0YXRlcykge1xuICBpZiAodHlwZW9mIGNhbmRpZGF0ZSA9PSBcInN0cmluZ1wiICYmIHNjYWxhck5hbWVzLmhhcyhjYW5kaWRhdGUpKSB7XG4gICAgcmV0dXJuIHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJUeXBlUmVmZXJlbmNlXCIpLCBuYW1lOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gKi8gKGNhbmRpZGF0ZSl9XG4gIH1cbiAgcmVxdWlyZVBsYWluKGNhbmRpZGF0ZSwgXCJvcGVyYXRpb24gdHlwZVwiKVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSB7XG4gICAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJraW5kXCIsIFwicmVzb3VyY2VcIl0sIFwib3duZWQgcmVzb3VyY2UgdHlwZVwiKVxuICAgIHJldHVybiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiT3duZWRSZXNvdXJjZVR5cGVcIiksIHJlc291cmNlSWQ6IHJlc29sdmVWMkRlY2xhcmF0aW9uKGNhbmRpZGF0ZS5yZXNvdXJjZSwgc3RhdGUsIHN0YXRlcywgXCJyZXNvdXJjZVwiKX1cbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wia2luZFwiLCBcInZhbHVlVHlwZVwiXSwgXCJvcHRpb25hbCB0eXBlXCIpXG4gICAgaWYgKHR5cGVvZiBjYW5kaWRhdGUudmFsdWVUeXBlICE9IFwic3RyaW5nXCIgfHwgIXNjYWxhck5hbWVzLmhhcyhjYW5kaWRhdGUudmFsdWVUeXBlKSkge1xuICAgICAgaW52YWxpZChcIkNhcGFiaWxpdHkgb3B0aW9uYWxzIG1heSBjb250YWluIG9ubHkgc2NhbGFyIHZhbHVlcy5cIilcbiAgICB9XG4gICAgcmV0dXJuIHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcHRpb25hbFR5cGVcIiksIHZhbHVlVHlwZToge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlR5cGVSZWZlcmVuY2VcIiksXG4gICAgICBuYW1lOiAvKiogQHR5cGUge2ltcG9ydChcIi4vdHlwZXMuanNcIikuU2VtYW50aWNUeXBlTmFtZX0gKi8gKGNhbmRpZGF0ZS52YWx1ZVR5cGUpfX1cbiAgfVxuICByZXR1cm4gaW52YWxpZChcIlVuc3VwcG9ydGVkIGNhcGFiaWxpdHkgdmFsdWUgdHlwZS5cIilcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIG9uZSBzY2hlbWEtdjIgcmVzb3VyY2UgdHJhbnNpdGlvbi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gY2FuZGlkYXRlIC0gQ2FuZGlkYXRlIHRyYW5zaXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0UGFyYW1ldGVyW119IHBhcmFtZXRlcnMgLSBOb3JtYWxpemVkIHBhcmFtZXRlcnMuXG4gKiBAcGFyYW0ge0NhcGFiaWxpdHlBdXRob3JpdHlWMlN0YXRlfSBzdGF0ZSAtIEN1cnJlbnQgbW9kdWxlIHN0YXRlLlxuICogQHBhcmFtIHtDYXBhYmlsaXR5QXV0aG9yaXR5VjJTdGF0ZVtdfSBzdGF0ZXMgLSBDb21wbGV0ZSBhdXRob3JpdHkgc3RhdGVzLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VGbG93fSBOb3JtYWxpemVkIHRyYW5zaXRpb24uXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVYyUmVzb3VyY2VGbG93KGNhbmRpZGF0ZSwgcGFyYW1ldGVycywgc3RhdGUsIHN0YXRlcykge1xuICByZXF1aXJlUGxhaW4oY2FuZGlkYXRlLCBcInJlc291cmNlIGZsb3dcIilcbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwibm9uZVwiKSB7XG4gICAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJraW5kXCJdLCBcInJlc291cmNlIGZsb3dcIilcbiAgICByZXR1cm4ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIm5vbmVcIil9XG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiYWNxdWlyZVwiKSB7XG4gICAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJraW5kXCIsIFwicmVzb3VyY2VcIl0sIFwiYWNxdWlzaXRpb24gZmxvd1wiKVxuICAgIHJldHVybiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiYWNxdWlyZVwiKSwgcmVzb3VyY2VJZDogcmVzb2x2ZVYyRGVjbGFyYXRpb24oY2FuZGlkYXRlLnJlc291cmNlLCBzdGF0ZSwgc3RhdGVzLCBcInJlc291cmNlXCIpfVxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcImJvcnJvd1wiIHx8IGNhbmRpZGF0ZS5raW5kID09IFwiY2xvc2VcIikge1xuICAgIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wia2luZFwiLCBcInBhcmFtZXRlckluZGV4XCIsIFwidGVybWluYWxGYWlsdXJlXCJdLCBgJHtjYW5kaWRhdGUua2luZH0gZmxvd2ApXG4gICAgY29uc3QgcGFyYW1ldGVySW5kZXggPSAvKiogQHR5cGUge251bWJlcn0gKi8gKGNhbmRpZGF0ZS5wYXJhbWV0ZXJJbmRleClcblxuICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIocGFyYW1ldGVySW5kZXgpIHx8IHBhcmFtZXRlckluZGV4IDwgMCB8fCBwYXJhbWV0ZXJJbmRleCA+PSBwYXJhbWV0ZXJzLmxlbmd0aCB8fFxuICAgICAgcGFyYW1ldGVyc1twYXJhbWV0ZXJJbmRleF0udHlwZS5raW5kICE9IFwiT3duZWRSZXNvdXJjZVR5cGVcIikgaW52YWxpZChgJHtjYW5kaWRhdGUua2luZH0gZmxvdyByZXF1aXJlcyBhbiBvd25lZCByZXNvdXJjZSBwYXJhbWV0ZXIuYClcbiAgICByZXR1cm4ge2tpbmQ6IC8qKiBAdHlwZSB7XCJib3Jyb3dcIiB8IFwiY2xvc2VcIn0gKi8gKGNhbmRpZGF0ZS5raW5kKSwgcGFyYW1ldGVySW5kZXgsXG4gICAgICB0ZXJtaW5hbEZhaWx1cmVJZDogcmVzb2x2ZVYyRGVjbGFyYXRpb24oY2FuZGlkYXRlLnRlcm1pbmFsRmFpbHVyZSwgc3RhdGUsIHN0YXRlcywgXCJmYWlsdXJlXCIpfVxuICB9XG4gIHJldHVybiBpbnZhbGlkKFwiVW5rbm93biByZXNvdXJjZS1mbG93IGtpbmQuXCIpXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25lIGxvY2FsIG9yIHF1YWxpZmllZCBzY2hlbWEtdjIgcmVzb3VyY2UvZmFpbHVyZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge0NhcGFiaWxpdHlBdXRob3JpdHlWMlN0YXRlfSBzdGF0ZSAtIEN1cnJlbnQgbW9kdWxlIHN0YXRlLlxuICogQHBhcmFtIHtDYXBhYmlsaXR5QXV0aG9yaXR5VjJTdGF0ZVtdfSBzdGF0ZXMgLSBDb21wbGV0ZSBhdXRob3JpdHkgc3RhdGVzLlxuICogQHBhcmFtIHtcInJlc291cmNlXCIgfCBcImZhaWx1cmVcIn0ga2luZCAtIERlY2xhcmF0aW9uIG5hbWVzcGFjZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IE5vcm1hbGl6ZWQgZGVjbGFyYXRpb24gaWRlbnRpdHkuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVWMkRlY2xhcmF0aW9uKGNhbmRpZGF0ZSwgc3RhdGUsIHN0YXRlcywga2luZCkge1xuICAvKiogQHR5cGUge0NhcGFiaWxpdHlBdXRob3JpdHlWMlN0YXRlIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgb3duZXIgPSBzdGF0ZVxuICBsZXQgbmFtZSA9IGNhbmRpZGF0ZVxuXG4gIGlmIChjYW5kaWRhdGUgIT09IG51bGwgJiYgdHlwZW9mIGNhbmRpZGF0ZSA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGNhbmRpZGF0ZSkpIHtcbiAgICByZXF1aXJlUGxhaW4oY2FuZGlkYXRlLCBgJHtraW5kfSByZWZlcmVuY2VgKVxuICAgIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wibW9kdWxlXCIsIFwibmFtZVwiXSwgYCR7a2luZH0gcmVmZXJlbmNlYClcbiAgICBpZiAodHlwZW9mIGNhbmRpZGF0ZS5tb2R1bGUgIT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgY2FuZGlkYXRlLm5hbWUgIT0gXCJzdHJpbmdcIikgaW52YWxpZChgSW52YWxpZCBxdWFsaWZpZWQgJHtraW5kfSByZWZlcmVuY2UuYClcbiAgICBvd25lciA9IHN0YXRlcy5maW5kKCh7aWRlbnRpdHl9KSA9PiBpZGVudGl0eSA9PSBjYW5kaWRhdGUubW9kdWxlKVxuICAgIG5hbWUgPSBjYW5kaWRhdGUubmFtZVxuICB9XG4gIGlmICghb3duZXIgfHwgdHlwZW9mIG5hbWUgIT0gXCJzdHJpbmdcIikgaW52YWxpZChgVW5rbm93biAke2tpbmR9IHJlZmVyZW5jZS5gKVxuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBraW5kID09IFwicmVzb3VyY2VcIiA/IG93bmVyLnJlc291cmNlTmFtZXMgOiBvd25lci5mYWlsdXJlTmFtZXNcbiAgY29uc3QgaWQgPSBkZWNsYXJhdGlvbnMuZ2V0KG5hbWUpXG5cbiAgaWYgKGlkID09PSB1bmRlZmluZWQpIGludmFsaWQoYFVua25vd24gJHtraW5kfSAnJHtvd25lci5pZGVudGl0eX0uJHtuYW1lfScuYClcbiAgcmV0dXJuIGlkXG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhbiBvcHRpb25hbCBwYXJzZSBhdXRob3JpdHkuXG4gKiBAcGFyYW0ge3Vua25vd259IGlucHV0IC0gT3B0aW9uYWwgY2FsbGVyIGlucHV0LlxuICogQHJldHVybnMge1JlYWRvbmx5PGltcG9ydChcIi4vdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eT4gfCB1bmRlZmluZWR9IEF1dGhvcml0eSBvciBsZWdhY3kgYWJzZW5jZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5vcm1hbGl6ZUNhcGFiaWxpdHlBdXRob3JpdHkoaW5wdXQpIHtcbiAgcmV0dXJuIGlucHV0ID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBjcmVhdGVDYXBhYmlsaXR5QXV0aG9yaXR5KGlucHV0KVxufVxuXG4vKipcbiAqIEZpbmRzIG9uZSBzb3VyY2UtdmlzaWJsZSBvcGVyYXRpb24gb25seSB3aGVuIGFuIG9yZGluYXJ5IHNvdXJjZSBkZWNsYXJhdGlvbiBkaWQgbm90IHdpbiByZXNvbHV0aW9uLlxuICogQHBhcmFtIHtyZWFkb25seSBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVmZmVjdENhcGFiaWxpdHlEZWNsYXJhdGlvbltdfSBjYXBhYmlsaXRpZXMgLSBBdXRob3JpemVkIGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gU291cmNlIHNwZWxsaW5nLlxuICogQHJldHVybnMge3tjYXBhYmlsaXR5OiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVmZmVjdENhcGFiaWxpdHlEZWNsYXJhdGlvbiwgb3BlcmF0aW9uOiBpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVmZmVjdE9wZXJhdGlvbkRlY2xhcmF0aW9ufSB8IHVuZGVmaW5lZH0gTWF0Y2guXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdXRob3JpemVkT3BlcmF0aW9uKGNhcGFiaWxpdGllcywgbmFtZSkge1xuICBmb3IgKGNvbnN0IGNhcGFiaWxpdHkgb2YgY2FwYWJpbGl0aWVzKSB7XG4gICAgY29uc3Qgb3BlcmF0aW9uID0gY2FwYWJpbGl0eS5vcGVyYXRpb25zLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT0gbmFtZSlcbiAgICBpZiAob3BlcmF0aW9uKSByZXR1cm4ge2NhcGFiaWxpdHksIG9wZXJhdGlvbn1cbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogQ2hlY2tzIHRoZSBib3VuZGVkIGNvbmZvcm1hbmNlIG9wZXJhdGlvbiBuYW1lc3BhY2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIENhbmRpZGF0ZSBzb3VyY2UgbmFtZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBuYW1lIGJlbG9uZ3MgdG8gVGFzayAwMzQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Rhc2swMzRPcGVyYXRpb25OYW1lKG5hbWUpIHtcbiAgcmV0dXJuIFtcInByb2JlQWNxdWlyZVwiLCBcInByb2JlQ2xvc2VcIiwgXCJwcm9iZUVmZmVjdFwiLCBcInByb2JlUmVhZFwiLCBcInByb2JlVHJhY2VcIl0uaW5jbHVkZXMobmFtZSlcbn1cblxuLyoqXG4gKiBDaGVja3MgdGhlIGV4YWN0IGJ1aWx0LWluIGNvbmZvcm1hbmNlIGNhcGFiaWxpdHkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3JlYWRvbmx5IGltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0Q2FwYWJpbGl0eURlY2xhcmF0aW9uW119IGNhcGFiaWxpdGllcyAtIENhbmRpZGF0ZSBncmFwaC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBncmFwaCBoYXMgdGhlIHN1cHBvcnRlZCBpZGVudGl0eSBhbmQgZGVjbGFyYXRpb24gb3JkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1Rhc2swMzRSZXNvdXJjZVByb2JlKGNhcGFiaWxpdGllcykge1xuICBpZiAoIWRlbnNlKGNhcGFiaWxpdGllcykgfHwgY2FwYWJpbGl0aWVzLmxlbmd0aCAhPSAxKSByZXR1cm4gZmFsc2VcbiAgY29uc3QgY2FwYWJpbGl0eSA9IGNhcGFiaWxpdGllc1swXVxuXG4gIGlmICghcGxhaW5XaXRoS2V5cyhjYXBhYmlsaXR5LCBbXCJhdXRob3JpdHlJZFwiLCBcImZhaWx1cmVzXCIsIFwiaWRcIiwgXCJraW5kXCIsIFwibmFtZVwiLCBcIm9wZXJhdGlvbnNcIiwgXCJyZXNvdXJjZXNcIl0pIHx8XG4gICAgY2FwYWJpbGl0eS5hdXRob3JpdHlJZCAhPSBcInNlbWFudGlmb2xkLnRhc2swMzQucmVzb3VyY2UtcHJvYmVcIiB8fCBjYXBhYmlsaXR5LmlkICE9IFwiY2FwYWJpbGl0eTowXCIgfHxcbiAgICBjYXBhYmlsaXR5LmtpbmQgIT0gXCJFZmZlY3RDYXBhYmlsaXR5RGVjbGFyYXRpb25cIiB8fCBjYXBhYmlsaXR5Lm5hbWUgIT0gXCJSZXNvdXJjZVByb2JlXCIgfHxcbiAgICAhZGVuc2UoY2FwYWJpbGl0eS5yZXNvdXJjZXMpIHx8ICFkZW5zZShjYXBhYmlsaXR5LmZhaWx1cmVzKSB8fCAhZGVuc2UoY2FwYWJpbGl0eS5vcGVyYXRpb25zKSB8fFxuICAgIGNhcGFiaWxpdHkucmVzb3VyY2VzLmxlbmd0aCAhPSAxIHx8IGNhcGFiaWxpdHkuZmFpbHVyZXMubGVuZ3RoICE9IDUgfHwgY2FwYWJpbGl0eS5vcGVyYXRpb25zLmxlbmd0aCAhPSA1KSByZXR1cm4gZmFsc2VcbiAgaWYgKCFleGFjdE5hbWVkRGVjbGFyYXRpb24oY2FwYWJpbGl0eS5yZXNvdXJjZXNbMF0sIFwiRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvblwiLCBcImNhcGFiaWxpdHk6MC9yZXNvdXJjZTowXCIsIFwiUHJvYmVSZXNvdXJjZVwiKSkgcmV0dXJuIGZhbHNlXG4gIGNvbnN0IGV4cGVjdGVkRmFpbHVyZXMgPSBbXCJQcm9iZU9wZXJhdGlvbkZhaWx1cmVcIiwgXCJQcm9iZUFjcXVpcmVGYWlsdXJlXCIsIFwiUHJvYmVSZWFkRmFpbHVyZVwiLCBcIlByb2JlQ2xvc2VGYWlsdXJlXCIsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiXVxuXG4gIGlmICghY2FwYWJpbGl0eS5mYWlsdXJlcy5ldmVyeSgoZmFpbHVyZSwgaW5kZXgpID0+XG4gICAgZXhhY3ROYW1lZERlY2xhcmF0aW9uKGZhaWx1cmUsIFwiRWZmZWN0RmFpbHVyZURlY2xhcmF0aW9uXCIsIGBjYXBhYmlsaXR5OjAvZmFpbHVyZToke2luZGV4fWAsIGV4cGVjdGVkRmFpbHVyZXNbaW5kZXhdKSkpIHJldHVybiBmYWxzZVxuICByZXR1cm4gY2FwYWJpbGl0eS5vcGVyYXRpb25zLmV2ZXJ5KChvcGVyYXRpb24sIGluZGV4KSA9PiBleGFjdFByb2JlT3BlcmF0aW9uKG9wZXJhdGlvbiwgaW5kZXgsIHRhc2swMzRQcm9iZU9wZXJhdGlvbnNbaW5kZXhdKSlcbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGV4YWN0IG5vcm1hbGl6ZWQgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBraW5kIC0gRXhwZWN0ZWQga2luZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpZCAtIEV4cGVjdGVkIGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBFeHBlY3RlZCBzb3VyY2UgbmFtZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBkZWNsYXJhdGlvbiBpcyBleGFjdC5cbiAqL1xuZnVuY3Rpb24gZXhhY3ROYW1lZERlY2xhcmF0aW9uKGNhbmRpZGF0ZSwga2luZCwgaWQsIG5hbWUpIHtcbiAgcmV0dXJuIHBsYWluV2l0aEtleXMoY2FuZGlkYXRlLCBbXCJpZFwiLCBcImtpbmRcIiwgXCJuYW1lXCJdKSAmJiBjYW5kaWRhdGUua2luZCA9PSBraW5kICYmIGNhbmRpZGF0ZS5pZCA9PSBpZCAmJiBjYW5kaWRhdGUubmFtZSA9PSBuYW1lXG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBleGFjdCBUYXNrIDAzNCBjb25mb3JtYW5jZSBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gaW5kZXggLSBFeHBlY3RlZCBvcGVyYXRpb24gaW5kZXguXG4gKiBAcGFyYW0geyh0eXBlb2YgdGFzazAzNFByb2JlT3BlcmF0aW9ucylbbnVtYmVyXX0gZXhwZWN0ZWQgLSBFeGFjdCBjb250cmFjdC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBvcGVyYXRpb24gbWF0Y2hlcyB0aGUgcHJvdGVjdGVkIGJpbmRpbmcuXG4gKi9cbmZ1bmN0aW9uIGV4YWN0UHJvYmVPcGVyYXRpb24oY2FuZGlkYXRlLCBpbmRleCwgZXhwZWN0ZWQpIHtcbiAgaWYgKCFwbGFpbldpdGhLZXlzKGNhbmRpZGF0ZSwgW1wiZWZmZWN0c1wiLCBcImZhaWx1cmVJZHNcIiwgXCJpZFwiLCBcImtpbmRcIiwgXCJuYW1lXCIsIFwicGFyYW1ldGVyc1wiLCBcInJlc291cmNlRmxvd1wiLCBcInJldHVyblR5cGVcIl0pIHx8XG4gICAgY2FuZGlkYXRlLmtpbmQgIT0gXCJFZmZlY3RPcGVyYXRpb25EZWNsYXJhdGlvblwiIHx8IGNhbmRpZGF0ZS5pZCAhPSBgY2FwYWJpbGl0eTowL29wZXJhdGlvbjoke2luZGV4fWAgfHxcbiAgICBjYW5kaWRhdGUubmFtZSAhPSBleHBlY3RlZC5uYW1lIHx8ICFzYW1lU3RyaW5nQXJyYXkoY2FuZGlkYXRlLmVmZmVjdHMsIFtcImhvc3RcIl0pIHx8XG4gICAgIXNhbWVTdHJpbmdBcnJheShjYW5kaWRhdGUuZmFpbHVyZUlkcywgZXhwZWN0ZWQuZmFpbHVyZXMpIHx8ICFkZW5zZShjYW5kaWRhdGUucGFyYW1ldGVycykgfHxcbiAgICBjYW5kaWRhdGUucGFyYW1ldGVycy5sZW5ndGggIT0gZXhwZWN0ZWQucGFyYW1ldGVycy5sZW5ndGggfHwgIWV4YWN0RmxhdE9iamVjdChjYW5kaWRhdGUucmVzb3VyY2VGbG93LCBleHBlY3RlZC5mbG93KSB8fFxuICAgICFleGFjdFByb2JlVHlwZShjYW5kaWRhdGUucmV0dXJuVHlwZSwgZXhwZWN0ZWQucmV0dXJuVHlwZSkpIHJldHVybiBmYWxzZVxuICByZXR1cm4gY2FuZGlkYXRlLnBhcmFtZXRlcnMuZXZlcnkoKHBhcmFtZXRlciwgcGFyYW1ldGVySW5kZXgpID0+IHBsYWluV2l0aEtleXMocGFyYW1ldGVyLCBbXCJuYW1lXCIsIFwidHlwZVwiXSkgJiZcbiAgICBwYXJhbWV0ZXIubmFtZSA9PSBleHBlY3RlZC5wYXJhbWV0ZXJzW3BhcmFtZXRlckluZGV4XVswXSAmJiBleGFjdFByb2JlVHlwZShwYXJhbWV0ZXIudHlwZSwgZXhwZWN0ZWQucGFyYW1ldGVyc1twYXJhbWV0ZXJJbmRleF1bMV0pKVxufVxuXG4vKipcbiAqIENoZWNrcyBvbmUgZXhhY3Qgbm9ybWFsaXplZCBjb25mb3JtYW5jZSB0eXBlLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBleHBlY3RlZCAtIENvbXBhY3QgZXhwZWN0ZWQgdHlwZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSB0eXBlIGlzIGV4YWN0LlxuICovXG5mdW5jdGlvbiBleGFjdFByb2JlVHlwZShjYW5kaWRhdGUsIGV4cGVjdGVkKSB7XG4gIGlmIChleHBlY3RlZCA9PSBcInJlc291cmNlXCIpIHtcbiAgICByZXR1cm4gcGxhaW5XaXRoS2V5cyhjYW5kaWRhdGUsIFtcImtpbmRcIiwgXCJyZXNvdXJjZUlkXCJdKSAmJiBjYW5kaWRhdGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIgJiZcbiAgICAgIGNhbmRpZGF0ZS5yZXNvdXJjZUlkID09IFwiY2FwYWJpbGl0eTowL3Jlc291cmNlOjBcIlxuICB9XG4gIGlmIChleHBlY3RlZCA9PSBcIm9wdGlvbmFsOnN0cmluZ1wiKSB7XG4gICAgcmV0dXJuIHBsYWluV2l0aEtleXMoY2FuZGlkYXRlLCBbXCJraW5kXCIsIFwidmFsdWVUeXBlXCJdKSAmJiBjYW5kaWRhdGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiICYmXG4gICAgICBleGFjdFByb2JlVHlwZShjYW5kaWRhdGUudmFsdWVUeXBlLCBcInN0cmluZ1wiKVxuICB9XG4gIHJldHVybiBwbGFpbldpdGhLZXlzKGNhbmRpZGF0ZSwgW1wia2luZFwiLCBcIm5hbWVcIl0pICYmIGNhbmRpZGF0ZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiICYmIGNhbmRpZGF0ZS5uYW1lID09IGV4cGVjdGVkXG59XG5cbi8qKlxuICogQ2hlY2tzIGFuIGV4YWN0IHNoYWxsb3cgb2JqZWN0IG9mIHByaW1pdGl2ZSBjb250cmFjdCBmaWVsZHMuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ge1JlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pn0gZXhwZWN0ZWQgLSBFeHBlY3RlZCBmaWVsZHMuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBhbGwgZmllbGRzIGFuZCB2YWx1ZXMgbWF0Y2guXG4gKi9cbmZ1bmN0aW9uIGV4YWN0RmxhdE9iamVjdChjYW5kaWRhdGUsIGV4cGVjdGVkKSB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhleHBlY3RlZClcbiAgcmV0dXJuIHBsYWluV2l0aEtleXMoY2FuZGlkYXRlLCBrZXlzKSAmJiBrZXlzLmV2ZXJ5KChrZXkpID0+IGNhbmRpZGF0ZVtrZXldID09IGV4cGVjdGVkW2tleV0pXG59XG5cbi8qKlxuICogQ2hlY2tzIGFuIGV4YWN0IGRlbnNlIHN0cmluZyBzZXF1ZW5jZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gY2FuZGlkYXRlIC0gQ2FuZGlkYXRlIHNlcXVlbmNlLlxuICogQHBhcmFtIHtyZWFkb25seSBzdHJpbmdbXX0gZXhwZWN0ZWQgLSBFeHBlY3RlZCBzdHJpbmdzLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgb3JkZXIgYW5kIHZhbHVlcyBtYXRjaC5cbiAqL1xuZnVuY3Rpb24gc2FtZVN0cmluZ0FycmF5KGNhbmRpZGF0ZSwgZXhwZWN0ZWQpIHtcbiAgcmV0dXJuIGRlbnNlKGNhbmRpZGF0ZSkgJiYgY2FuZGlkYXRlLmxlbmd0aCA9PSBleHBlY3RlZC5sZW5ndGggJiYgY2FuZGlkYXRlLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlID09IGV4cGVjdGVkW2luZGV4XSlcbn1cblxuLyoqXG4gKiBDaGVja3MgYW4gb3JkaW5hcnkgb2JqZWN0J3MgZXhhY3Qgb3duLWtleSBzZXQuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBvYmplY3QuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBrZXlzIC0gRXhhY3Qga2V5cy5cbiAqIEByZXR1cm5zIHtjYW5kaWRhdGUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj59IFdoZXRoZXIgdGhlIG9iamVjdCBhbmQgZmllbGRzIGFyZSBleGFjdC5cbiAqL1xuZnVuY3Rpb24gcGxhaW5XaXRoS2V5cyhjYW5kaWRhdGUsIGtleXMpIHtcbiAgcmV0dXJuIGNhbmRpZGF0ZSAhPT0gbnVsbCAmJiB0eXBlb2YgY2FuZGlkYXRlID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoY2FuZGlkYXRlKSAmJlxuICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZihjYW5kaWRhdGUpID09IE9iamVjdC5wcm90b3R5cGUgJiYgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gWy4uLmtleXNdLnNvcnQoKS5qb2luKFwiLFwiKVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgb25lIGNsb3NlZCBvcGVyYXRpb24gdmFsdWUgdHlwZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gY2FuZGlkYXRlIC0gUmF3IHZhbHVlIHR5cGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIHN0cmluZz59IHJlc291cmNlTmFtZXMgLSBSZXNvdXJjZSBpZGVudGl0aWVzIGJ5IG5hbWUuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gTm9ybWFsaXplZCB0eXBlLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVWYWx1ZVR5cGUoY2FuZGlkYXRlLCByZXNvdXJjZU5hbWVzKSB7XG4gIGlmICh0eXBlb2YgY2FuZGlkYXRlID09IFwic3RyaW5nXCIgJiYgc2NhbGFyTmFtZXMuaGFzKGNhbmRpZGF0ZSkpIHtcbiAgICByZXR1cm4ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlR5cGVSZWZlcmVuY2VcIiksIG5hbWU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSAqLyAoY2FuZGlkYXRlKX1cbiAgfVxuICByZXF1aXJlUGxhaW4oY2FuZGlkYXRlLCBcIm9wZXJhdGlvbiB0eXBlXCIpXG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHtcbiAgICByZXF1aXJlS2V5cyhjYW5kaWRhdGUsIFtcImtpbmRcIiwgXCJyZXNvdXJjZVwiXSwgXCJvd25lZCByZXNvdXJjZSB0eXBlXCIpXG4gICAgaWYgKHR5cGVvZiBjYW5kaWRhdGUucmVzb3VyY2UgIT0gXCJzdHJpbmdcIiB8fCAhcmVzb3VyY2VOYW1lcy5oYXMoY2FuZGlkYXRlLnJlc291cmNlKSkgaW52YWxpZChgVW5rbm93biBvd25lZCByZXNvdXJjZSAnJHtTdHJpbmcoY2FuZGlkYXRlLnJlc291cmNlKX0nLmApXG4gICAgcmV0dXJuIHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPd25lZFJlc291cmNlVHlwZVwiKSwgcmVzb3VyY2VJZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyZXNvdXJjZU5hbWVzLmdldChjYW5kaWRhdGUucmVzb3VyY2UpKX1cbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgIHJlcXVpcmVLZXlzKGNhbmRpZGF0ZSwgW1wia2luZFwiLCBcInZhbHVlVHlwZVwiXSwgXCJvcHRpb25hbCB0eXBlXCIpXG4gICAgaWYgKHR5cGVvZiBjYW5kaWRhdGUudmFsdWVUeXBlICE9IFwic3RyaW5nXCIgfHwgIXNjYWxhck5hbWVzLmhhcyhjYW5kaWRhdGUudmFsdWVUeXBlKSkgaW52YWxpZChcIkNhcGFiaWxpdHkgb3B0aW9uYWxzIG1heSBjb250YWluIG9ubHkgc2NhbGFyIHZhbHVlcy5cIilcbiAgICByZXR1cm4ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk9wdGlvbmFsVHlwZVwiKSwgdmFsdWVUeXBlOiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHlwZVJlZmVyZW5jZVwiKSxcbiAgICAgIG5hbWU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY1R5cGVOYW1lfSAqLyAoY2FuZGlkYXRlLnZhbHVlVHlwZSl9fVxuICB9XG4gIHJldHVybiBpbnZhbGlkKFwiVW5zdXBwb3J0ZWQgY2FwYWJpbGl0eSB2YWx1ZSB0eXBlLlwiKVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgb25lIGNsb3NlZCByZXNvdXJjZSB0cmFuc2l0aW9uLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBSYXcgdHJhbnNpdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uW119IHJlc291cmNlcyAtIERlY2xhcmVkIHJlc291cmNlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgc3RyaW5nPn0gcmVzb3VyY2VOYW1lcyAtIFJlc291cmNlIGlkZW50aXRpZXMgYnkgbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgc3RyaW5nPn0gZmFpbHVyZU5hbWVzIC0gRmFpbHVyZSBpZGVudGl0aWVzIGJ5IG5hbWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vdHlwZXMuanNcIikuRWZmZWN0UGFyYW1ldGVyW119IHBhcmFtZXRlcnMgLSBOb3JtYWxpemVkIG9yZGVyZWQgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRmxvd30gTm9ybWFsaXplZCBmbG93LlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVSZXNvdXJjZUZsb3coY2FuZGlkYXRlLCByZXNvdXJjZXMsIHJlc291cmNlTmFtZXMsIGZhaWx1cmVOYW1lcywgcGFyYW1ldGVycykge1xuICByZXF1aXJlUGxhaW4oY2FuZGlkYXRlLCBcInJlc291cmNlIGZsb3dcIilcbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwibm9uZVwiKSB7XG4gICAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJraW5kXCJdLCBcInJlc291cmNlIGZsb3dcIilcbiAgICByZXR1cm4ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIm5vbmVcIil9XG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiYWNxdWlyZVwiKSB7XG4gICAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJraW5kXCIsIFwicmVzb3VyY2VcIl0sIFwiYWNxdWlzaXRpb24gZmxvd1wiKVxuICAgIGlmICh0eXBlb2YgY2FuZGlkYXRlLnJlc291cmNlICE9IFwic3RyaW5nXCIgfHwgIXJlc291cmNlTmFtZXMuaGFzKGNhbmRpZGF0ZS5yZXNvdXJjZSkpIGludmFsaWQoXCJBY3F1aXNpdGlvbiBuYW1lcyBhbiB1bmRlY2xhcmVkIHJlc291cmNlLlwiKVxuICAgIGNvbnN0IHJlc291cmNlSWQgPSByZXNvdXJjZU5hbWVzLmdldChjYW5kaWRhdGUucmVzb3VyY2UpXG4gICAgaWYgKCFyZXNvdXJjZXMuc29tZSgoe2lkfSkgPT4gaWQgPT0gcmVzb3VyY2VJZCkpIGludmFsaWQoXCJBY3F1aXNpdGlvbiByZXNvdXJjZSBpZGVudGl0eSBpcyBpbnZhbGlkLlwiKVxuICAgIHJldHVybiB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiYWNxdWlyZVwiKSwgcmVzb3VyY2VJZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyZXNvdXJjZUlkKX1cbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJib3Jyb3dcIiB8fCBjYW5kaWRhdGUua2luZCA9PSBcImNsb3NlXCIpIHtcbiAgICByZXF1aXJlS2V5cyhjYW5kaWRhdGUsIFtcImtpbmRcIiwgXCJwYXJhbWV0ZXJJbmRleFwiLCBcInRlcm1pbmFsRmFpbHVyZVwiXSwgYCR7Y2FuZGlkYXRlLmtpbmR9IGZsb3dgKVxuICAgIGNvbnN0IHBhcmFtZXRlckluZGV4ID0gLyoqIEB0eXBlIHtudW1iZXJ9ICovIChjYW5kaWRhdGUucGFyYW1ldGVySW5kZXgpXG4gICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihwYXJhbWV0ZXJJbmRleCkgfHwgcGFyYW1ldGVySW5kZXggPCAwIHx8IHBhcmFtZXRlckluZGV4ID49IHBhcmFtZXRlcnMubGVuZ3RoIHx8XG4gICAgICBwYXJhbWV0ZXJzW3BhcmFtZXRlckluZGV4XS50eXBlLmtpbmQgIT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSBpbnZhbGlkKGAke2NhbmRpZGF0ZS5raW5kfSBmbG93IHJlcXVpcmVzIGFuIG93bmVkIHJlc291cmNlIHBhcmFtZXRlci5gKVxuICAgIGlmICh0eXBlb2YgY2FuZGlkYXRlLnRlcm1pbmFsRmFpbHVyZSAhPSBcInN0cmluZ1wiIHx8ICFmYWlsdXJlTmFtZXMuaGFzKGNhbmRpZGF0ZS50ZXJtaW5hbEZhaWx1cmUpKSB7XG4gICAgICBpbnZhbGlkKGAke2NhbmRpZGF0ZS5raW5kfSBmbG93IHJlcXVpcmVzIGEgZGVjbGFyZWQgdGVybWluYWwgZmFpbHVyZS5gKVxuICAgIH1cbiAgICByZXR1cm4ge2tpbmQ6IC8qKiBAdHlwZSB7XCJib3Jyb3dcIiB8IFwiY2xvc2VcIn0gKi8gKGNhbmRpZGF0ZS5raW5kKSwgcGFyYW1ldGVySW5kZXgsXG4gICAgICB0ZXJtaW5hbEZhaWx1cmVJZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChmYWlsdXJlTmFtZXMuZ2V0KGNhbmRpZGF0ZS50ZXJtaW5hbEZhaWx1cmUpKX1cbiAgfVxuICByZXR1cm4gaW52YWxpZChcIlVua25vd24gcmVzb3VyY2UtZmxvdyBraW5kLlwiKVxufVxuXG4vKipcbiAqIFJlcXVpcmVzIGV2ZXJ5IG93bmVkIHBhcmFtZXRlci9yZXN1bHQgdG8gaGF2ZSBvbmUgY29tcGxldGUgbW9kZWxlZCB0cmFuc2l0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBPcGVyYXRpb24gbmFtZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5FZmZlY3RQYXJhbWV0ZXJbXX0gcGFyYW1ldGVycyAtIE9yZGVyZWQgcGFyYW1ldGVycy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gcmV0dXJuVHlwZSAtIE9wZXJhdGlvbiByZXN1bHQuXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBmYWlsdXJlSWRzIC0gRGVjbGFyZWQgZmFpbHVyZSBpZGVudGl0aWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRmxvd30gcmVzb3VyY2VGbG93IC0gRGVjbGFyZWQgdHJhbnNpdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVJlc291cmNlT3BlcmF0aW9uKG5hbWUsIHBhcmFtZXRlcnMsIHJldHVyblR5cGUsIGZhaWx1cmVJZHMsIHJlc291cmNlRmxvdykge1xuICBjb25zdCBvd25lZFBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzLmZsYXRNYXAoKHBhcmFtZXRlciwgaW5kZXgpID0+IHBhcmFtZXRlci50eXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiID8gW2luZGV4XSA6IFtdKVxuXG4gIGlmIChyZXNvdXJjZUZsb3cua2luZCA9PSBcIm5vbmVcIikge1xuICAgIGlmIChvd25lZFBhcmFtZXRlcnMubGVuZ3RoID4gMCB8fCByZXR1cm5UeXBlLmtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSB7XG4gICAgICBpbnZhbGlkKGBPcGVyYXRpb24gJyR7bmFtZX0nIGhhcyBhbiBvd25lZCB2YWx1ZSB3aXRob3V0IGEgcmVzb3VyY2UgdHJhbnNpdGlvbi5gKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAocmVzb3VyY2VGbG93LmtpbmQgPT0gXCJhY3F1aXJlXCIpIHtcbiAgICBpZiAob3duZWRQYXJhbWV0ZXJzLmxlbmd0aCA+IDAgfHwgcmV0dXJuVHlwZS5raW5kICE9IFwiT3duZWRSZXNvdXJjZVR5cGVcIiB8fCByZXR1cm5UeXBlLnJlc291cmNlSWQgIT0gcmVzb3VyY2VGbG93LnJlc291cmNlSWQpIHtcbiAgICAgIGludmFsaWQoYE9wZXJhdGlvbiAnJHtuYW1lfScgYWNxdWlzaXRpb24gcmVzdWx0IGRvZXMgbm90IG1hdGNoIGl0cyByZXNvdXJjZSB0cmFuc2l0aW9uLmApXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmIChvd25lZFBhcmFtZXRlcnMubGVuZ3RoICE9IDEgfHwgb3duZWRQYXJhbWV0ZXJzWzBdICE9IHJlc291cmNlRmxvdy5wYXJhbWV0ZXJJbmRleCB8fFxuICAgIHJldHVyblR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIgfHwgIWZhaWx1cmVJZHMuaW5jbHVkZXMocmVzb3VyY2VGbG93LnRlcm1pbmFsRmFpbHVyZUlkKSkge1xuICAgIGludmFsaWQoYE9wZXJhdGlvbiAnJHtuYW1lfScgYm9ycm93L2Nsb3NlIHRyYW5zaXRpb24gaXMgaW5jb21wbGV0ZS5gKVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBzaW5nbGUtZmllbGQgbmFtZWQgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIFJhdyBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgc3RyaW5nIHwgdW5kZWZpbmVkPn0gbmFtZXMgLSBBbHJlYWR5LWRlY2xhcmVkIG5hbWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBEaWFnbm9zdGljIHN1YmplY3QuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmVxdWlyZU5hbWVkKGNhbmRpZGF0ZSwgbmFtZXMsIHN1YmplY3QpIHtcbiAgcmVxdWlyZVBsYWluKGNhbmRpZGF0ZSwgc3ViamVjdClcbiAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJuYW1lXCJdLCBzdWJqZWN0KVxuICBpZiAodHlwZW9mIGNhbmRpZGF0ZS5uYW1lICE9IFwic3RyaW5nXCIgfHwgIWRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChjYW5kaWRhdGUubmFtZSkgfHwgbmFtZXMuaGFzKGNhbmRpZGF0ZS5uYW1lKSkge1xuICAgIGludmFsaWQoYER1cGxpY2F0ZSBvciBpbnZhbGlkICR7c3ViamVjdH0gbmFtZS5gKVxuICB9XG4gIG5hbWVzLnNldChjYW5kaWRhdGUubmFtZSwgdW5kZWZpbmVkKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBhbmQgcmVzZXJ2ZXMgb25lIGRlY2xhcmF0aW9uIG5hbWUuXG4gKiBAcGFyYW0ge3Vua25vd259IG5hbWUgLSBDYW5kaWRhdGUgbmFtZS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IG5hbWVzIC0gQWxyZWFkeS1kZWNsYXJlZCBuYW1lcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gRGlhZ25vc3RpYyBzdWJqZWN0LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlcXVpcmVOYW1lKG5hbWUsIG5hbWVzLCBzdWJqZWN0KSB7XG4gIGlmICh0eXBlb2YgbmFtZSAhPSBcInN0cmluZ1wiIHx8ICFkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3QobmFtZSkgfHwgbmFtZXMuaGFzKG5hbWUpKSBpbnZhbGlkKGBEdXBsaWNhdGUgb3IgaW52YWxpZCAke3N1YmplY3R9IG5hbWUuYClcbiAgbmFtZXMuYWRkKG5hbWUpXG59XG5cbi8qKlxuICogUmVxdWlyZXMgYW4gb3JkaW5hcnkgb2JqZWN0LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSB2YWx1ZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gRGlhZ25vc3RpYyBzdWJqZWN0LlxuICogQHJldHVybnMge2Fzc2VydHMgdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj59IEFzc2VydHMgYW4gb3JkaW5hcnkgb2JqZWN0LlxuICovXG5mdW5jdGlvbiByZXF1aXJlUGxhaW4odmFsdWUsIHN1YmplY3QpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHZhbHVlKSB8fCBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpICE9IE9iamVjdC5wcm90b3R5cGUpIGludmFsaWQoYEludmFsaWQgJHtzdWJqZWN0fSBvYmplY3QuYClcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyBvbmUgZXhhY3QgZmllbGQgc2V0LlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gdmFsdWUgLSBDYW5kaWRhdGUgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmdbXX0ga2V5cyAtIFJlcXVpcmVkIGtleXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ViamVjdCAtIERpYWdub3N0aWMgc3ViamVjdC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZXF1aXJlS2V5cyh2YWx1ZSwga2V5cywgc3ViamVjdCkge1xuICBpZiAoT2JqZWN0LmtleXModmFsdWUpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBbLi4ua2V5c10uc29ydCgpLmpvaW4oXCIsXCIpKSBpbnZhbGlkKGBJbnZhbGlkICR7c3ViamVjdH0gZmllbGRzLmApXG59XG5cbi8qKlxuICogQ2hlY2tzIGFuIG9yZGVyZWQgZGVuc2UgYXJyYXkuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIGFycmF5LlxuICogQHJldHVybnMge3ZhbHVlIGlzIHVua25vd25bXX0gV2hldGhlciB0aGUgdmFsdWUgaXMgZGVuc2UuXG4gKi9cbmZ1bmN0aW9uIGRlbnNlKHZhbHVlKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5ldmVyeSgoX2l0ZW0sIGluZGV4KSA9PiBPYmplY3QuaGFzT3duKHZhbHVlLCBpbmRleCkpXG59XG5cbi8qKlxuICogUmVjdXJzaXZlbHkgZnJlZXplcyBhIGRldGFjaGVkIGF1dGhvcml0eSBncmFwaC5cbiAqIEB0ZW1wbGF0ZSB7b2JqZWN0fSBWYWx1ZVxuICogQHBhcmFtIHtWYWx1ZX0gdmFsdWUgLSBPYmplY3QgdG8gZnJlZXplLlxuICogQHJldHVybnMge1JlYWRvbmx5PFZhbHVlPn0gRnJvemVuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZGVlcEZyZWV6ZSh2YWx1ZSkge1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIE9iamVjdC52YWx1ZXModmFsdWUpKSB7XG4gICAgaWYgKGNoaWxkICYmIHR5cGVvZiBjaGlsZCA9PSBcIm9iamVjdFwiICYmICFPYmplY3QuaXNGcm96ZW4oY2hpbGQpKSBkZWVwRnJlZXplKGNoaWxkKVxuICB9XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHZhbHVlKVxufVxuXG4vKipcbiAqIFJhaXNlcyBvbmUgc3RhYmxlIGF1dGhvcml0eSBkaWFnbm9zdGljLlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBEaWFnbm9zdGljIG1lc3NhZ2UuXG4gKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIGludmFsaWQobWVzc2FnZSkge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIklOVkFMSURfQ0FQQUJJTElUWV9BVVRIT1JJVFlcIiwgbGFuZ3VhZ2U6IFwiY2FwYWJpbGl0eVwiLCBtZXNzYWdlfSlcbn1cbiJdfQ==
|