semantifold 0.3.0 → 0.5.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 +61 -15
- package/build/index.d.ts +52 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +60 -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/android.d.ts +49 -0
- package/build/src/backends/android.d.ts.map +1 -0
- package/build/src/backends/android.js +1274 -0
- 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 +160 -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 +33 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +138 -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 +83 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1309 -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 +2174 -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 +255 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +491 -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 +177 -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 +3108 -178
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +730 -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/android.md +79 -0
- package/docs/architecture.md +47 -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 +238 -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 +17 -7
- package/docs/specification.md +5 -0
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +381 -4
- package/docs/webassembly.md +52 -0
- package/index.js +66 -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/android.js +1370 -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 +166 -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 +144 -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 +1408 -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 +2314 -115
- 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 +545 -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 +182 -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 +810 -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,880 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { SemantifoldDiagnostic } from "../diagnostic.js";
|
|
3
|
+
const identityPattern = /^[a-z][a-z0-9.-]*$/u;
|
|
4
|
+
const declarationNamePattern = /^[A-Za-z_][A-Za-z0-9_]*$/u;
|
|
5
|
+
const scalarNames = new Set(["boolean", "integer", "string"]);
|
|
6
|
+
const component = "(0|[1-9][0-9]*)";
|
|
7
|
+
const exactVersionPattern = new RegExp(`^${component}\\.${component}\\.${component}$`, "u");
|
|
8
|
+
const rangePattern = new RegExp(`^${component}(?:\\.${component}){0,2}$`, "u");
|
|
9
|
+
const semanticsValues = {
|
|
10
|
+
blocking: new Set(["synchronous"]),
|
|
11
|
+
close: new Set(["not-applicable", "use-after-close-fails", "repeated-close-fails"]),
|
|
12
|
+
eof: new Set(["not-applicable", "absent-value"]),
|
|
13
|
+
encoding: new Set(["not-applicable", "utf-8"]),
|
|
14
|
+
newline: new Set(["not-applicable", "strip-line-terminator", "retain-line-terminator", "append-lf-if-missing"]),
|
|
15
|
+
ownership: new Set(["not-applicable", "acquired", "borrowed", "consumed"]),
|
|
16
|
+
timeout: new Set(["none"])
|
|
17
|
+
};
|
|
18
|
+
/** @typedef {[number, number, number]} VersionTuple */
|
|
19
|
+
/** @typedef {{lower: VersionTuple, upper: VersionTuple | null}} VersionRange */
|
|
20
|
+
/** @typedef {{module: string, name: string}} CanonicalDeclarationReference */
|
|
21
|
+
/**
|
|
22
|
+
* @typedef StdlibContractOperation
|
|
23
|
+
* @property {{module: string, operation: string, range: VersionRange}[]} dependencies - Canonical operation dependencies.
|
|
24
|
+
* @property {["host"]} effects - Closed effect declaration.
|
|
25
|
+
* @property {"left-to-right"} evaluationOrder - Canonical argument evaluation order.
|
|
26
|
+
* @property {(string | CanonicalDeclarationReference)[]} failures - Declared failure names.
|
|
27
|
+
* @property {string} name - Operation name.
|
|
28
|
+
* @property {{name: string, type: string | CanonicalDeclarationReference}[]} parameters - Ordered parameters.
|
|
29
|
+
* @property {object} resourceFlow - Closed resource transition.
|
|
30
|
+
* @property {string | CanonicalDeclarationReference} returnType - Closed return type spelling.
|
|
31
|
+
* @property {Record<string, string>} semantics - Closed canonical semantics fields.
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* @typedef StdlibContractModule
|
|
35
|
+
* @property {{module: string, range: VersionRange}[]} dependencies - Versioned declaration dependencies.
|
|
36
|
+
* @property {{name: string}[]} failures - Ordered failure declarations.
|
|
37
|
+
* @property {string} identity - Canonical module identity.
|
|
38
|
+
* @property {StdlibContractOperation[]} operations - Ordered operation declarations.
|
|
39
|
+
* @property {{name: string}[]} resources - Ordered resource declarations.
|
|
40
|
+
* @property {string} version - Exact registered version.
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* @typedef StdlibContract
|
|
44
|
+
* @property {{module: string, range: VersionRange}[]} dependencies - Versioned declaration dependencies.
|
|
45
|
+
* @property {{name: string}[]} failures - Ordered failure declarations.
|
|
46
|
+
* @property {string} identity - Canonical module identity.
|
|
47
|
+
* @property {StdlibContractOperation[]} operations - Ordered operation declarations.
|
|
48
|
+
* @property {{name: string}[]} resources - Ordered resource declarations.
|
|
49
|
+
* @property {"SemantifoldStdlibContract"} schema - Contract schema discriminator.
|
|
50
|
+
* @property {1} schemaVersion - Contract schema version.
|
|
51
|
+
* @property {string} version - Resolved exact version.
|
|
52
|
+
*/
|
|
53
|
+
/**
|
|
54
|
+
* @typedef StdlibContractRegistry
|
|
55
|
+
* @property {{identity: string, versions: string[]}[]} modules - Registered modules in stable order.
|
|
56
|
+
* @property {(identity: string, range?: string) => StdlibContract} resolveModule - Versioned module resolution.
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Parses one exact X.Y.Z standard-library version.
|
|
60
|
+
* @param {unknown} value - Candidate version.
|
|
61
|
+
* @returns {VersionTuple | null} Parsed version or null when malformed.
|
|
62
|
+
*/
|
|
63
|
+
export function parseStdlibVersion(value) {
|
|
64
|
+
if (typeof value != "string" || !exactVersionPattern.test(value))
|
|
65
|
+
return null;
|
|
66
|
+
const [major, minor, patch] = value.split(".").map((part) => Number(part));
|
|
67
|
+
return [major, minor, patch];
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Parses one X, X.Y, or X.Y.Z standard-library version range.
|
|
71
|
+
* @param {unknown} value - Candidate range.
|
|
72
|
+
* @returns {VersionRange | null} Half-open range or null when malformed.
|
|
73
|
+
*/
|
|
74
|
+
export function parseStdlibVersionRange(value) {
|
|
75
|
+
if (typeof value != "string" || !rangePattern.test(value))
|
|
76
|
+
return null;
|
|
77
|
+
const parts = value.split(".").map((part) => Number(part));
|
|
78
|
+
const major = parts[0];
|
|
79
|
+
const minor = parts.length > 1 ? parts[1] : 0;
|
|
80
|
+
const patch = parts.length > 2 ? parts[2] : 0;
|
|
81
|
+
if (parts.length == 1)
|
|
82
|
+
return { lower: [major, 0, 0], upper: [major + 1, 0, 0] };
|
|
83
|
+
if (parts.length == 2)
|
|
84
|
+
return { lower: [major, minor, 0], upper: [major, minor + 1, 0] };
|
|
85
|
+
return { lower: [major, minor, patch], upper: [major, minor, patch + 1] };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Compares two exact version tuples.
|
|
89
|
+
* @param {VersionTuple} left - Left version.
|
|
90
|
+
* @param {VersionTuple} right - Right version.
|
|
91
|
+
* @returns {number} Negative, zero, or positive ordering.
|
|
92
|
+
*/
|
|
93
|
+
export function compareStdlibVersions(left, right) {
|
|
94
|
+
for (let index = 0; index < 3; index += 1) {
|
|
95
|
+
if (left[index] != right[index])
|
|
96
|
+
return left[index] < right[index] ? -1 : 1;
|
|
97
|
+
}
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Derives one protected native provider entry name.
|
|
102
|
+
* @param {string} target - Adopted provider target language.
|
|
103
|
+
* @param {string} module - Legacy operation name or canonical module identity.
|
|
104
|
+
* @param {string} [operation] - Qualified canonical operation name.
|
|
105
|
+
* @returns {string} Protected native entry name.
|
|
106
|
+
*/
|
|
107
|
+
export function protectedEntryName(target, module, operation) {
|
|
108
|
+
if (typeof target != "string" || !/^[a-z][a-z0-9-]*$/u.test(target) ||
|
|
109
|
+
typeof module != "string" || (operation !== undefined && (typeof operation != "string" ||
|
|
110
|
+
!declarationNamePattern.test(operation))))
|
|
111
|
+
invalidContract("Protected provider entry components are invalid.");
|
|
112
|
+
if (operation === undefined) {
|
|
113
|
+
if (!declarationNamePattern.test(module))
|
|
114
|
+
invalidContract("Protected provider operation name is invalid.");
|
|
115
|
+
return `__semantifold_provider_${target}_${module}`;
|
|
116
|
+
}
|
|
117
|
+
if (!identityPattern.test(module))
|
|
118
|
+
invalidContract("Protected provider module identity is invalid.");
|
|
119
|
+
const encodedModule = [...module].map((character) => character.charCodeAt(0).toString(16).padStart(2, "0")).join("");
|
|
120
|
+
return `__semantifold_provider_${target}_m${encodedModule.length}_${encodedModule}_${operation}`;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Parses one protected native provider entry name.
|
|
124
|
+
* @param {string} name - Candidate protected entry name.
|
|
125
|
+
* @returns {{target: string, module?: string, operation: string} | null} Parsed binding or null when unparseable.
|
|
126
|
+
*/
|
|
127
|
+
export function parseProtectedEntryName(name) {
|
|
128
|
+
const qualified = /^__semantifold_provider_([a-z][a-z0-9-]*)_m([0-9]+)_([0-9a-f]+)_([A-Za-z_][A-Za-z0-9_]*)$/u.exec(name);
|
|
129
|
+
if (qualified) {
|
|
130
|
+
const encodedLength = Number(qualified[2]);
|
|
131
|
+
const encoded = qualified[3];
|
|
132
|
+
if (!Number.isSafeInteger(encodedLength) || encodedLength != encoded.length || encoded.length % 2 != 0)
|
|
133
|
+
return null;
|
|
134
|
+
let module = "";
|
|
135
|
+
for (let index = 0; index < encoded.length; index += 2)
|
|
136
|
+
module += String.fromCharCode(Number.parseInt(encoded.slice(index, index + 2), 16));
|
|
137
|
+
if (!identityPattern.test(module) || protectedEntryName(qualified[1], module, qualified[4]) != name)
|
|
138
|
+
return null;
|
|
139
|
+
return { module, operation: qualified[4], target: qualified[1] };
|
|
140
|
+
}
|
|
141
|
+
const match = /^__semantifold_provider_([a-z][a-z0-9-]*)_(.+)$/u.exec(name);
|
|
142
|
+
if (!match)
|
|
143
|
+
return null;
|
|
144
|
+
return { operation: match[2], target: match[1] };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Intersects two half-open version ranges.
|
|
148
|
+
* @param {VersionRange} left - Left range.
|
|
149
|
+
* @param {VersionRange} right - Right range.
|
|
150
|
+
* @returns {VersionRange | null} Intersection or null when empty.
|
|
151
|
+
*/
|
|
152
|
+
export function intersectStdlibVersionRanges(left, right) {
|
|
153
|
+
const lower = compareStdlibVersions(left.lower, right.lower) >= 0 ? left.lower : right.lower;
|
|
154
|
+
const upper = left.upper === null ? right.upper : right.upper === null ? left.upper :
|
|
155
|
+
compareStdlibVersions(left.upper, right.upper) <= 0 ? left.upper : right.upper;
|
|
156
|
+
if (upper !== null && compareStdlibVersions(lower, upper) >= 0)
|
|
157
|
+
return null;
|
|
158
|
+
return { lower, upper };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Checks whether one exact version satisfies one half-open range.
|
|
162
|
+
* @param {VersionTuple} version - Candidate version.
|
|
163
|
+
* @param {VersionRange} range - Declared range.
|
|
164
|
+
* @returns {boolean} Whether the version satisfies the range.
|
|
165
|
+
*/
|
|
166
|
+
export function stdlibVersionSatisfies(version, range) {
|
|
167
|
+
if (compareStdlibVersions(version, range.lower) < 0)
|
|
168
|
+
return false;
|
|
169
|
+
return range.upper === null || compareStdlibVersions(version, range.upper) < 0;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Creates the built-in versioned canonical stdlib contract registry.
|
|
173
|
+
* @param {unknown} records - Optional override record set; built-in probe contract by default.
|
|
174
|
+
* @returns {Readonly<StdlibContractRegistry>} Frozen registry.
|
|
175
|
+
*/
|
|
176
|
+
export function createStdlibContractRegistry(records = builtinContracts()) {
|
|
177
|
+
if (!isDenseArray(records))
|
|
178
|
+
invalidContract("Canonical contract records must be an ordered dense array.");
|
|
179
|
+
/** @type {Map<string, Map<string, StdlibContractModule>>} */
|
|
180
|
+
const modules = new Map();
|
|
181
|
+
for (const candidate of records) {
|
|
182
|
+
const record = validateContractRecord(candidate);
|
|
183
|
+
const versions = modules.get(record.identity) ?? new Map();
|
|
184
|
+
if (versions.has(record.version))
|
|
185
|
+
invalidContract(`Duplicate canonical contract '${record.identity}' version '${record.version}'.`);
|
|
186
|
+
versions.set(record.version, record);
|
|
187
|
+
modules.set(record.identity, versions);
|
|
188
|
+
}
|
|
189
|
+
for (const record of modules.values()) {
|
|
190
|
+
for (const module of record.values())
|
|
191
|
+
validateContractDependencies(module, modules);
|
|
192
|
+
}
|
|
193
|
+
const frozenModules = [...modules.entries()]
|
|
194
|
+
.map(([identity, versions]) => ({
|
|
195
|
+
identity,
|
|
196
|
+
versions: [...versions.keys()].map((version) => /** @type {VersionTuple} */ (parseStdlibVersion(version)))
|
|
197
|
+
.sort(compareStdlibVersions)
|
|
198
|
+
.map(([major, minor, patch]) => `${major}.${minor}.${patch}`)
|
|
199
|
+
}))
|
|
200
|
+
.map(deepFreeze);
|
|
201
|
+
const store = deepFreeze(/** @type {{modules: [string, Readonly<Map<string, Readonly<StdlibContractModule>>>][]}} */ ({
|
|
202
|
+
modules: [...modules.entries()].map(([identity, versions]) => [identity, deepFreeze(versions)])
|
|
203
|
+
}));
|
|
204
|
+
return Object.freeze(/** @type {StdlibContractRegistry} */ ({
|
|
205
|
+
modules: Object.freeze(frozenModules),
|
|
206
|
+
resolveModule(identity, range) {
|
|
207
|
+
return resolveRegistryModule(store, identity, range);
|
|
208
|
+
}
|
|
209
|
+
}));
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Resolves one module identity plus optional range against one registry store.
|
|
213
|
+
* @param {{modules: [string, Readonly<Map<string, Readonly<StdlibContractModule>>>][]}} store - Registry store.
|
|
214
|
+
* @param {string} identity - Canonical module identity.
|
|
215
|
+
* @param {string | undefined} [range] - Declared version range.
|
|
216
|
+
* @returns {StdlibContract} Detached frozen contract.
|
|
217
|
+
*/
|
|
218
|
+
function resolveRegistryModule(store, identity, range) {
|
|
219
|
+
const versions = store.modules.find(([candidate]) => candidate == identity)?.[1];
|
|
220
|
+
if (!versions)
|
|
221
|
+
unknownModule(identity);
|
|
222
|
+
const parsed = range === undefined ? /** @type {VersionRange} */ ({ lower: [0, 0, 0], upper: null }) : parseStdlibVersionRange(range);
|
|
223
|
+
if (!parsed)
|
|
224
|
+
malformedRange();
|
|
225
|
+
/** @type {VersionTuple | undefined} */
|
|
226
|
+
let resolved;
|
|
227
|
+
for (const version of versions.keys()) {
|
|
228
|
+
const tuple = /** @type {VersionTuple} */ (parseStdlibVersion(version));
|
|
229
|
+
if (stdlibVersionSatisfies(tuple, parsed) && (resolved === undefined || compareStdlibVersions(tuple, resolved) > 0)) {
|
|
230
|
+
resolved = tuple;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
if (resolved === undefined)
|
|
234
|
+
incompatibleVersion(identity);
|
|
235
|
+
const record = /** @type {Readonly<StdlibContractModule>} */ (versions.get(`${resolved[0]}.${resolved[1]}.${resolved[2]}`));
|
|
236
|
+
return deepFreeze({
|
|
237
|
+
dependencies: record.dependencies,
|
|
238
|
+
failures: record.failures,
|
|
239
|
+
identity: record.identity,
|
|
240
|
+
operations: record.operations,
|
|
241
|
+
resources: record.resources,
|
|
242
|
+
schema: /** @type {const} */ ("SemantifoldStdlibContract"),
|
|
243
|
+
schemaVersion: /** @type {const} */ (1),
|
|
244
|
+
version: `${resolved[0]}.${resolved[1]}.${resolved[2]}`
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Lists the built-in canonical stdlib modules with their registered versions.
|
|
249
|
+
* @returns {Readonly<{identity: string, versions: string[]}[]>} Frozen module list.
|
|
250
|
+
*/
|
|
251
|
+
export function listStdlibModules() {
|
|
252
|
+
return builtinRegistry.modules;
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Resolves one built-in canonical stdlib module by identity and optional range.
|
|
256
|
+
* @param {string} identity - Canonical module identity.
|
|
257
|
+
* @param {string} [range] - Declared version range.
|
|
258
|
+
* @returns {StdlibContract} Detached frozen contract.
|
|
259
|
+
*/
|
|
260
|
+
export function resolveStdlibModule(identity, range) {
|
|
261
|
+
return builtinRegistry.resolveModule(identity, range);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Declares the built-in Task 034 resource-probe canonical contract.
|
|
265
|
+
* @returns {unknown} Unvalidated built-in record.
|
|
266
|
+
*/
|
|
267
|
+
function builtinProbeContract() {
|
|
268
|
+
return {
|
|
269
|
+
dependencies: [],
|
|
270
|
+
failures: [
|
|
271
|
+
{ name: "ProbeOperationFailure" },
|
|
272
|
+
{ name: "ProbeAcquireFailure" },
|
|
273
|
+
{ name: "ProbeReadFailure" },
|
|
274
|
+
{ name: "ProbeCloseFailure" },
|
|
275
|
+
{ name: "ProbeResourceClosed" }
|
|
276
|
+
],
|
|
277
|
+
identity: "semantifold.task034.resource-probe",
|
|
278
|
+
operations: [
|
|
279
|
+
{
|
|
280
|
+
dependencies: [],
|
|
281
|
+
effects: ["host"],
|
|
282
|
+
evaluationOrder: "left-to-right",
|
|
283
|
+
failures: ["ProbeOperationFailure"],
|
|
284
|
+
name: "probeEffect",
|
|
285
|
+
parameters: [{ name: "label", type: "string" }, { name: "value", type: "integer" }, { name: "fail", type: "boolean" }],
|
|
286
|
+
resourceFlow: { kind: "none" },
|
|
287
|
+
returnType: "integer",
|
|
288
|
+
semantics: canonicalSemantics()
|
|
289
|
+
},
|
|
290
|
+
{
|
|
291
|
+
dependencies: [],
|
|
292
|
+
effects: ["host"],
|
|
293
|
+
evaluationOrder: "left-to-right",
|
|
294
|
+
failures: ["ProbeAcquireFailure"],
|
|
295
|
+
name: "probeAcquire",
|
|
296
|
+
parameters: [{ name: "fail", type: "boolean" }],
|
|
297
|
+
resourceFlow: { kind: "acquire", resource: "ProbeResource" },
|
|
298
|
+
returnType: "ProbeResource",
|
|
299
|
+
semantics: canonicalSemantics({ ownership: "acquired" })
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
dependencies: [],
|
|
303
|
+
effects: ["host"],
|
|
304
|
+
evaluationOrder: "left-to-right",
|
|
305
|
+
failures: ["ProbeReadFailure", "ProbeResourceClosed"],
|
|
306
|
+
name: "probeRead",
|
|
307
|
+
parameters: [{ name: "resource", type: "ProbeResource" }, { name: "fail", type: "boolean" }],
|
|
308
|
+
resourceFlow: { kind: "borrow", parameterIndex: 0, terminalFailure: "ProbeResourceClosed" },
|
|
309
|
+
returnType: "optional:string",
|
|
310
|
+
semantics: canonicalSemantics({
|
|
311
|
+
close: "use-after-close-fails",
|
|
312
|
+
eof: "absent-value",
|
|
313
|
+
encoding: "utf-8",
|
|
314
|
+
newline: "strip-line-terminator",
|
|
315
|
+
ownership: "borrowed"
|
|
316
|
+
})
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
dependencies: [],
|
|
320
|
+
effects: ["host"],
|
|
321
|
+
evaluationOrder: "left-to-right",
|
|
322
|
+
failures: ["ProbeCloseFailure", "ProbeResourceClosed"],
|
|
323
|
+
name: "probeClose",
|
|
324
|
+
parameters: [{ name: "resource", type: "ProbeResource" }, { name: "fail", type: "boolean" }],
|
|
325
|
+
resourceFlow: { kind: "close", parameterIndex: 0, terminalFailure: "ProbeResourceClosed" },
|
|
326
|
+
returnType: "void",
|
|
327
|
+
semantics: canonicalSemantics({ close: "repeated-close-fails", ownership: "consumed" })
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
dependencies: [],
|
|
331
|
+
effects: ["host"],
|
|
332
|
+
evaluationOrder: "left-to-right",
|
|
333
|
+
failures: [],
|
|
334
|
+
name: "probeTrace",
|
|
335
|
+
parameters: [],
|
|
336
|
+
resourceFlow: { kind: "none" },
|
|
337
|
+
returnType: "string",
|
|
338
|
+
semantics: canonicalSemantics()
|
|
339
|
+
}
|
|
340
|
+
],
|
|
341
|
+
resources: [{ name: "ProbeResource" }],
|
|
342
|
+
version: "1.0.0"
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Declares the complete built-in canonical registry input.
|
|
347
|
+
* @returns {unknown[]} Unvalidated built-in records.
|
|
348
|
+
*/
|
|
349
|
+
function builtinContracts() {
|
|
350
|
+
return [builtinProbeContract(), builtinSocketClientContract(), builtinTextStreamContract(),
|
|
351
|
+
builtinOutputContract(), builtinResourceContract()];
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Declares the built-in SocketClient v1 contract.
|
|
355
|
+
* @returns {unknown} Unvalidated SocketClient v1 record.
|
|
356
|
+
*/
|
|
357
|
+
function builtinSocketClientContract() {
|
|
358
|
+
const byteStream = { module: "semantifold.resource", name: "ByteStream" };
|
|
359
|
+
return {
|
|
360
|
+
dependencies: [{ module: "semantifold.resource", range: "1" }],
|
|
361
|
+
failures: [{ name: "InvalidHost" }, { name: "InvalidPort" }, { name: "ConnectionFailure" }],
|
|
362
|
+
identity: "semantifold.socket-client",
|
|
363
|
+
operations: [{
|
|
364
|
+
dependencies: [], effects: ["host"], evaluationOrder: "left-to-right",
|
|
365
|
+
failures: ["InvalidHost", "InvalidPort", "ConnectionFailure"], name: "v1_connect",
|
|
366
|
+
parameters: [{ name: "host", type: "string" }, { name: "port", type: "integer" }],
|
|
367
|
+
resourceFlow: { kind: "acquire", resource: byteStream }, returnType: byteStream,
|
|
368
|
+
semantics: canonicalSemantics({ ownership: "acquired" })
|
|
369
|
+
}],
|
|
370
|
+
resources: [],
|
|
371
|
+
version: "1.0.0"
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Declares the built-in TextStream v1 contract.
|
|
376
|
+
* @returns {unknown} Unvalidated TextStream v1 record.
|
|
377
|
+
*/
|
|
378
|
+
function builtinTextStreamContract() {
|
|
379
|
+
const byteStream = { module: "semantifold.resource", name: "ByteStream" };
|
|
380
|
+
const resourceClosed = { module: "semantifold.resource", name: "ResourceClosed" };
|
|
381
|
+
return {
|
|
382
|
+
dependencies: [{ module: "semantifold.resource", range: "1" }],
|
|
383
|
+
failures: [{ name: "ReadFailure" }, { name: "DecodeFailure" }],
|
|
384
|
+
identity: "semantifold.text-stream",
|
|
385
|
+
operations: [{
|
|
386
|
+
dependencies: [], effects: ["host"], evaluationOrder: "left-to-right",
|
|
387
|
+
failures: ["ReadFailure", "DecodeFailure", resourceClosed], name: "v1_read_line",
|
|
388
|
+
parameters: [{ name: "resource", type: byteStream }],
|
|
389
|
+
resourceFlow: { kind: "borrow", parameterIndex: 0, terminalFailure: resourceClosed },
|
|
390
|
+
returnType: "optional:string",
|
|
391
|
+
semantics: canonicalSemantics({ close: "use-after-close-fails", eof: "absent-value", encoding: "utf-8",
|
|
392
|
+
newline: "retain-line-terminator", ownership: "borrowed" })
|
|
393
|
+
}],
|
|
394
|
+
resources: [],
|
|
395
|
+
version: "1.0.0"
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Declares the built-in Output v1 contract.
|
|
400
|
+
* @returns {unknown} Unvalidated Output v1 record.
|
|
401
|
+
*/
|
|
402
|
+
function builtinOutputContract() {
|
|
403
|
+
return {
|
|
404
|
+
dependencies: [], failures: [{ name: "WriteFailure" }], identity: "semantifold.output",
|
|
405
|
+
operations: [{
|
|
406
|
+
dependencies: [], effects: ["host"], evaluationOrder: "left-to-right", failures: ["WriteFailure"],
|
|
407
|
+
name: "v1_write_line", parameters: [{ name: "text", type: "string" }], resourceFlow: { kind: "none" },
|
|
408
|
+
returnType: "void", semantics: canonicalSemantics({ encoding: "utf-8", newline: "append-lf-if-missing" })
|
|
409
|
+
}],
|
|
410
|
+
resources: [], version: "1.0.0"
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Declares the built-in Resource v1 contract.
|
|
415
|
+
* @returns {unknown} Unvalidated Resource v1 record.
|
|
416
|
+
*/
|
|
417
|
+
function builtinResourceContract() {
|
|
418
|
+
return {
|
|
419
|
+
dependencies: [], failures: [{ name: "CloseFailure" }, { name: "ResourceClosed" }], identity: "semantifold.resource",
|
|
420
|
+
operations: [{
|
|
421
|
+
dependencies: [], effects: ["host"], evaluationOrder: "left-to-right",
|
|
422
|
+
failures: ["CloseFailure", "ResourceClosed"], name: "v1_close",
|
|
423
|
+
parameters: [{ name: "resource", type: "ByteStream" }],
|
|
424
|
+
resourceFlow: { kind: "close", parameterIndex: 0, terminalFailure: "ResourceClosed" }, returnType: "void",
|
|
425
|
+
semantics: canonicalSemantics({ close: "repeated-close-fails", ownership: "consumed" })
|
|
426
|
+
}],
|
|
427
|
+
resources: [{ name: "ByteStream" }], version: "1.0.0"
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
/**
|
|
431
|
+
* Builds one closed semantics declaration with canonical defaults.
|
|
432
|
+
* @param {Partial<Record<keyof typeof semanticsValues, string>>} [overrides] - Non-default closed values.
|
|
433
|
+
* @returns {Record<string, string>} Closed semantics fields.
|
|
434
|
+
*/
|
|
435
|
+
function canonicalSemantics(overrides = {}) {
|
|
436
|
+
return {
|
|
437
|
+
blocking: "synchronous",
|
|
438
|
+
close: "not-applicable",
|
|
439
|
+
eof: "not-applicable",
|
|
440
|
+
encoding: "not-applicable",
|
|
441
|
+
newline: "not-applicable",
|
|
442
|
+
ownership: "not-applicable",
|
|
443
|
+
timeout: "none",
|
|
444
|
+
...overrides
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
/**
|
|
448
|
+
* Validates one canonical contract record and returns a detached clone.
|
|
449
|
+
* @param {unknown} candidate - Candidate record.
|
|
450
|
+
* @returns {StdlibContractModule} Detached record.
|
|
451
|
+
*/
|
|
452
|
+
function validateContractRecord(candidate) {
|
|
453
|
+
if (!isPlainObject(candidate))
|
|
454
|
+
invalidContract("Every canonical contract record must be a plain object.");
|
|
455
|
+
requireKeys(candidate, ["dependencies", "failures", "identity", "operations", "resources", "version"], "contract record");
|
|
456
|
+
const identity = /** @type {string} */ (candidate.identity);
|
|
457
|
+
if (typeof identity != "string" || !identityPattern.test(identity))
|
|
458
|
+
invalidContract("Canonical contract identity is invalid.");
|
|
459
|
+
const version = /** @type {string} */ (candidate.version);
|
|
460
|
+
if (parseStdlibVersion(version) === null)
|
|
461
|
+
invalidContract(`Canonical contract version '${String(version)}' is invalid.`);
|
|
462
|
+
const resources = validateNamedList(candidate.resources, "resource");
|
|
463
|
+
const failures = validateNamedList(candidate.failures, "failure");
|
|
464
|
+
const resourceNames = new Set(resources.map(({ name }) => name));
|
|
465
|
+
const failureNames = new Set(failures.map(({ name }) => name));
|
|
466
|
+
const operationNames = new Set();
|
|
467
|
+
const dependencies = validateModuleDependencies(candidate.dependencies, identity);
|
|
468
|
+
if (!isDenseArray(candidate.operations))
|
|
469
|
+
invalidContract("Canonical contract operations must be a dense array.");
|
|
470
|
+
const operations = /** @type {unknown[]} */ (candidate.operations).map((operation) => validateContractOperation(operation, resourceNames, failureNames, operationNames));
|
|
471
|
+
return deepFreeze({
|
|
472
|
+
dependencies,
|
|
473
|
+
failures,
|
|
474
|
+
identity,
|
|
475
|
+
operations,
|
|
476
|
+
resources,
|
|
477
|
+
version: /** @type {string} */ (version)
|
|
478
|
+
});
|
|
479
|
+
}
|
|
480
|
+
/**
|
|
481
|
+
* Validates one canonical contract operation.
|
|
482
|
+
* @param {unknown} candidate - Candidate operation.
|
|
483
|
+
* @param {Set<string>} resourceNames - Declared resource names.
|
|
484
|
+
* @param {Set<string>} failureNames - Declared failure names.
|
|
485
|
+
* @param {Set<string>} operationNames - Already-declared operation names.
|
|
486
|
+
* @returns {StdlibContractOperation} Detached operation.
|
|
487
|
+
*/
|
|
488
|
+
function validateContractOperation(candidate, resourceNames, failureNames, operationNames) {
|
|
489
|
+
if (!isPlainObject(candidate))
|
|
490
|
+
invalidContract("Every canonical contract operation must be a plain object.");
|
|
491
|
+
requireKeys(candidate, ["dependencies", "effects", "evaluationOrder", "failures", "name", "parameters", "resourceFlow", "returnType", "semantics"], "contract operation");
|
|
492
|
+
const name = /** @type {string} */ (candidate.name);
|
|
493
|
+
if (typeof name != "string" || !declarationNamePattern.test(name) || operationNames.has(name)) {
|
|
494
|
+
invalidContract("Canonical contract operation name is invalid or duplicate.");
|
|
495
|
+
}
|
|
496
|
+
operationNames.add(name);
|
|
497
|
+
if (!isDenseArray(candidate.effects) || candidate.effects.length != 1 || candidate.effects[0] != "host") {
|
|
498
|
+
invalidContract(`Operation '${name}' requires the single host effect declaration.`);
|
|
499
|
+
}
|
|
500
|
+
if (candidate.evaluationOrder != "left-to-right")
|
|
501
|
+
invalidContract(`Operation '${name}' requires left-to-right evaluation.`);
|
|
502
|
+
if (!isDenseArray(candidate.failures)) {
|
|
503
|
+
invalidContract(`Operation '${name}' declares unknown or duplicate failures.`);
|
|
504
|
+
}
|
|
505
|
+
const failures = candidate.failures.map((failure) => normalizeDeclarationReference(failure, failureNames, `Operation '${name}' failure`));
|
|
506
|
+
if (new Set(failures.map(referenceKey)).size != failures.length)
|
|
507
|
+
invalidContract(`Operation '${name}' repeats a declared failure.`);
|
|
508
|
+
const parameterNames = new Set();
|
|
509
|
+
/** @type {{name: string, type: string | CanonicalDeclarationReference}[]} */
|
|
510
|
+
const parameters = [];
|
|
511
|
+
if (!isDenseArray(candidate.parameters))
|
|
512
|
+
invalidContract(`Operation '${name}' parameters must be a dense array.`);
|
|
513
|
+
for (const parameter of /** @type {unknown[]} */ (candidate.parameters)) {
|
|
514
|
+
if (!isPlainObject(parameter))
|
|
515
|
+
invalidContract(`Operation '${name}' parameters must be plain objects.`);
|
|
516
|
+
requireKeys(parameter, ["name", "type"], `operation '${name}' parameter`);
|
|
517
|
+
const parameterName = /** @type {string} */ (parameter.name);
|
|
518
|
+
if (typeof parameterName != "string" || !declarationNamePattern.test(parameterName) || parameterNames.has(parameterName)) {
|
|
519
|
+
invalidContract(`Operation '${name}' parameter name is invalid or duplicate.`);
|
|
520
|
+
}
|
|
521
|
+
parameterNames.add(parameterName);
|
|
522
|
+
const parameterType = normalizeCanonicalValueType(parameter.type, resourceNames, `operation '${name}' parameter '${parameterName}'`);
|
|
523
|
+
if (parameterType === null) {
|
|
524
|
+
invalidContract(`Operation '${name}' parameter '${parameterName}' type is outside the closed canonical value set.`);
|
|
525
|
+
}
|
|
526
|
+
parameters.push({ name: parameterName, type: parameterType });
|
|
527
|
+
}
|
|
528
|
+
const returnType = candidate.returnType == "void" ? "void" : normalizeCanonicalValueType(candidate.returnType, resourceNames, `operation '${name}' return type`);
|
|
529
|
+
if (returnType === null) {
|
|
530
|
+
invalidContract(`Operation '${name}' return type is outside the closed canonical value set.`);
|
|
531
|
+
}
|
|
532
|
+
const resourceFlow = validateContractResourceFlow(candidate.resourceFlow, parameters, failures, name);
|
|
533
|
+
const dependencies = validateOperationDependencies(candidate.dependencies);
|
|
534
|
+
const semantics = validateContractSemantics(candidate.semantics, name);
|
|
535
|
+
return deepFreeze({
|
|
536
|
+
dependencies,
|
|
537
|
+
effects: /** @type {const} */ (["host"]),
|
|
538
|
+
evaluationOrder: /** @type {const} */ ("left-to-right"),
|
|
539
|
+
failures,
|
|
540
|
+
name,
|
|
541
|
+
parameters,
|
|
542
|
+
resourceFlow,
|
|
543
|
+
returnType,
|
|
544
|
+
semantics
|
|
545
|
+
});
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Validates one closed canonical value type spelling.
|
|
549
|
+
* @param {unknown} candidate - Candidate type.
|
|
550
|
+
* @param {Set<string>} resourceNames - Declared resource names.
|
|
551
|
+
* @param {string} _subject - Diagnostic subject reserved for caller context.
|
|
552
|
+
* @returns {string | CanonicalDeclarationReference | null} Detached type or null.
|
|
553
|
+
*/
|
|
554
|
+
function normalizeCanonicalValueType(candidate, resourceNames, _subject) {
|
|
555
|
+
if (typeof candidate == "string") {
|
|
556
|
+
if (scalarNames.has(candidate) || resourceNames.has(candidate))
|
|
557
|
+
return candidate;
|
|
558
|
+
const optional = /^optional:([a-z]+)$/u.exec(candidate);
|
|
559
|
+
return optional && scalarNames.has(optional[1]) ? candidate : null;
|
|
560
|
+
}
|
|
561
|
+
if (isPlainObject(candidate) && Object.keys(candidate).sort().join(",") == "module,name" &&
|
|
562
|
+
typeof candidate.module == "string" && identityPattern.test(candidate.module) && typeof candidate.name == "string" &&
|
|
563
|
+
declarationNamePattern.test(candidate.name))
|
|
564
|
+
return { module: candidate.module, name: candidate.name };
|
|
565
|
+
return null;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Validates one closed resource transition against its parameters and failures.
|
|
569
|
+
* @param {unknown} candidate - Candidate transition.
|
|
570
|
+
* @param {{name: string, type: string | CanonicalDeclarationReference}[]} parameters - Validated parameters.
|
|
571
|
+
* @param {(string | CanonicalDeclarationReference)[]} failures - Validated failure names.
|
|
572
|
+
* @param {string} operation - Operation name.
|
|
573
|
+
* @returns {object} Detached transition.
|
|
574
|
+
*/
|
|
575
|
+
function validateContractResourceFlow(candidate, parameters, failures, operation) {
|
|
576
|
+
if (!isPlainObject(candidate))
|
|
577
|
+
invalidContract(`Operation '${operation}' requires a resource flow declaration.`);
|
|
578
|
+
const ownedParameters = parameters.flatMap((parameter, index) => isOwnedCanonicalType(parameter.type) ? [index] : []);
|
|
579
|
+
if (Object.keys(candidate).sort().join(",") == "kind" && candidate.kind == "none") {
|
|
580
|
+
if (ownedParameters.length > 0)
|
|
581
|
+
invalidContract(`Operation '${operation}' owns a parameter without a transition.`);
|
|
582
|
+
return deepFreeze({ kind: /** @type {const} */ ("none") });
|
|
583
|
+
}
|
|
584
|
+
if (Object.keys(candidate).sort().join(",") == "kind,resource" && candidate.kind == "acquire") {
|
|
585
|
+
const resource = typeof candidate.resource == "string" && declarationNamePattern.test(candidate.resource)
|
|
586
|
+
? candidate.resource
|
|
587
|
+
: normalizeCanonicalValueType(candidate.resource, new Set(), `operation '${operation}' acquisition`);
|
|
588
|
+
if (resource === null || ownedParameters.length > 0) {
|
|
589
|
+
invalidContract(`Operation '${operation}' acquisition flow is incomplete.`);
|
|
590
|
+
}
|
|
591
|
+
return deepFreeze({ kind: /** @type {const} */ ("acquire"), resource });
|
|
592
|
+
}
|
|
593
|
+
if (["borrow", "close"].includes(String(candidate.kind)) &&
|
|
594
|
+
Object.keys(candidate).sort().join(",") == "kind,parameterIndex,terminalFailure") {
|
|
595
|
+
const parameterIndex = /** @type {number} */ (candidate.parameterIndex);
|
|
596
|
+
if (!Number.isSafeInteger(parameterIndex) || parameterIndex < 0 || parameterIndex >= parameters.length ||
|
|
597
|
+
ownedParameters.length != 1 || ownedParameters[0] != parameterIndex ||
|
|
598
|
+
!failures.some((failure) => referenceKey(failure) == referenceKey(candidate.terminalFailure))) {
|
|
599
|
+
invalidContract(`Operation '${operation}' ${String(candidate.kind)} flow is incomplete.`);
|
|
600
|
+
}
|
|
601
|
+
return deepFreeze({ kind: /** @type {"borrow" | "close"} */ (candidate.kind), parameterIndex,
|
|
602
|
+
terminalFailure: normalizeFailureFlowReference(candidate.terminalFailure) });
|
|
603
|
+
}
|
|
604
|
+
return invalidContract(`Operation '${operation}' declares an unknown resource flow.`);
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Validates one canonical operation dependency list.
|
|
608
|
+
* @param {unknown} candidate - Candidate dependencies.
|
|
609
|
+
* @returns {{module: string, operation: string, range: VersionRange}[]} Detached dependencies.
|
|
610
|
+
*/
|
|
611
|
+
function validateOperationDependencies(candidate) {
|
|
612
|
+
if (!isDenseArray(candidate))
|
|
613
|
+
invalidContract("Canonical contract dependencies must be a dense array.");
|
|
614
|
+
/** @type {{module: string, operation: string, range: VersionRange}[]} */
|
|
615
|
+
const dependencies = [];
|
|
616
|
+
for (const dependency of candidate) {
|
|
617
|
+
if (!isPlainObject(dependency))
|
|
618
|
+
invalidContract("Every canonical contract dependency must be a plain object.");
|
|
619
|
+
requireKeys(dependency, ["module", "operation", "range"], "contract dependency");
|
|
620
|
+
const module = /** @type {string} */ (dependency.module);
|
|
621
|
+
const operation = /** @type {string} */ (dependency.operation);
|
|
622
|
+
const range = parseStdlibVersionRange(dependency.range);
|
|
623
|
+
if (typeof module != "string" || !identityPattern.test(module) ||
|
|
624
|
+
typeof operation != "string" || !declarationNamePattern.test(operation) || range === null) {
|
|
625
|
+
invalidContract("Canonical contract dependency module, operation, or range is invalid.");
|
|
626
|
+
}
|
|
627
|
+
dependencies.push({ module, operation, range });
|
|
628
|
+
}
|
|
629
|
+
return dependencies;
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Validates canonical operation dependencies against the complete registry identity set.
|
|
633
|
+
* @param {StdlibContractModule} record - Validated record.
|
|
634
|
+
* @param {Map<string, Map<string, StdlibContractModule>>} modules - All registered module versions.
|
|
635
|
+
* @returns {void}
|
|
636
|
+
*/
|
|
637
|
+
function validateContractDependencies(record, modules) {
|
|
638
|
+
const allowedDependencies = new Map(record.dependencies.map((dependency) => [dependency.module, dependency.range]));
|
|
639
|
+
for (const dependency of record.dependencies) {
|
|
640
|
+
const versions = modules.get(dependency.module);
|
|
641
|
+
if (!versions || ![...versions.keys()].some((version) => stdlibVersionSatisfies(/** @type {VersionTuple} */ (parseStdlibVersion(version)), dependency.range))) {
|
|
642
|
+
invalidContract(`Canonical module '${record.identity}' depends on missing or incompatible module '${dependency.module}'.`);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
for (const operation of record.operations) {
|
|
646
|
+
for (const reference of operation.parameters.map(({ type }) => type).concat([operation.returnType]).filter(isDeclarationReference)) {
|
|
647
|
+
validateForeignDeclarationReference(record, reference, "resource", allowedDependencies, modules);
|
|
648
|
+
}
|
|
649
|
+
for (const reference of operation.failures.filter(isDeclarationReference)) {
|
|
650
|
+
validateForeignDeclarationReference(record, reference, "failure", allowedDependencies, modules);
|
|
651
|
+
}
|
|
652
|
+
for (const dependency of operation.dependencies) {
|
|
653
|
+
if (!modules.has(dependency.module)) {
|
|
654
|
+
invalidContract(`Operation '${operation.name}' depends on unknown canonical module '${dependency.module}'.`);
|
|
655
|
+
}
|
|
656
|
+
if (dependency.module == record.identity && dependency.operation == operation.name) {
|
|
657
|
+
invalidContract(`Operation '${operation.name}' declares a self-cycle dependency.`);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Validates declaration-only module dependencies.
|
|
664
|
+
* @param {unknown} candidate - Candidate dependency list.
|
|
665
|
+
* @param {string} identity - Owning module identity.
|
|
666
|
+
* @returns {{module: string, range: VersionRange}[]} Detached dependencies.
|
|
667
|
+
*/
|
|
668
|
+
function validateModuleDependencies(candidate, identity) {
|
|
669
|
+
if (!isDenseArray(candidate))
|
|
670
|
+
invalidContract("Canonical module dependencies must be a dense array.");
|
|
671
|
+
const names = new Set();
|
|
672
|
+
return candidate.map((dependency) => {
|
|
673
|
+
if (!isPlainObject(dependency))
|
|
674
|
+
invalidContract("Every canonical module dependency must be a plain object.");
|
|
675
|
+
requireKeys(dependency, ["module", "range"], "module dependency");
|
|
676
|
+
const module = /** @type {string} */ (dependency.module);
|
|
677
|
+
const range = parseStdlibVersionRange(dependency.range);
|
|
678
|
+
if (typeof module != "string" || !identityPattern.test(module) || module == identity || names.has(module) || range === null) {
|
|
679
|
+
invalidContract("Canonical module dependency is invalid, duplicate, self-referential, or malformed.");
|
|
680
|
+
}
|
|
681
|
+
names.add(module);
|
|
682
|
+
return { module, range };
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
/**
|
|
686
|
+
* Validates one dependency-qualified resource or failure reference.
|
|
687
|
+
* @param {StdlibContractModule} record - Owning module.
|
|
688
|
+
* @param {CanonicalDeclarationReference} reference - Qualified declaration.
|
|
689
|
+
* @param {"resource" | "failure"} kind - Declaration kind.
|
|
690
|
+
* @param {Map<string, VersionRange>} allowedDependencies - Direct dependency ranges.
|
|
691
|
+
* @param {Map<string, Map<string, StdlibContractModule>>} modules - Registry modules.
|
|
692
|
+
* @returns {void}
|
|
693
|
+
*/
|
|
694
|
+
function validateForeignDeclarationReference(record, reference, kind, allowedDependencies, modules) {
|
|
695
|
+
const range = allowedDependencies.get(reference.module);
|
|
696
|
+
if (!range)
|
|
697
|
+
invalidContract(`Canonical module '${record.identity}' uses undeclared dependency '${reference.module}'.`);
|
|
698
|
+
const versions = /** @type {Map<string, StdlibContractModule>} */ (modules.get(reference.module));
|
|
699
|
+
const matches = [...versions.values()].filter((module) => stdlibVersionSatisfies(/** @type {VersionTuple} */ (parseStdlibVersion(module.version)), range));
|
|
700
|
+
const declarations = kind == "resource" ? matches.flatMap(({ resources }) => resources) : matches.flatMap(({ failures }) => failures);
|
|
701
|
+
if (!declarations.some(({ name }) => name == reference.name)) {
|
|
702
|
+
invalidContract(`Canonical ${kind} '${reference.module}.${reference.name}' is not declared by a compatible dependency.`);
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
/**
|
|
706
|
+
* Normalizes one local or dependency-qualified declaration reference.
|
|
707
|
+
* @param {unknown} candidate - Candidate reference.
|
|
708
|
+
* @param {Set<string>} localNames - Declared local names.
|
|
709
|
+
* @param {string} subject - Diagnostic subject.
|
|
710
|
+
* @returns {string | CanonicalDeclarationReference} Detached reference.
|
|
711
|
+
*/
|
|
712
|
+
function normalizeDeclarationReference(candidate, localNames, subject) {
|
|
713
|
+
if (typeof candidate == "string" && localNames.has(candidate))
|
|
714
|
+
return candidate;
|
|
715
|
+
if (isDeclarationReference(candidate))
|
|
716
|
+
return { module: candidate.module, name: candidate.name };
|
|
717
|
+
return invalidContract(`${subject} is not a declared local or qualified canonical declaration.`);
|
|
718
|
+
}
|
|
719
|
+
/**
|
|
720
|
+
* Normalizes a terminal failure reference after membership validation.
|
|
721
|
+
* @param {unknown} candidate - Candidate failure reference.
|
|
722
|
+
* @returns {string | CanonicalDeclarationReference} Detached reference.
|
|
723
|
+
*/
|
|
724
|
+
function normalizeFailureFlowReference(candidate) {
|
|
725
|
+
if (typeof candidate == "string")
|
|
726
|
+
return candidate;
|
|
727
|
+
if (isDeclarationReference(candidate))
|
|
728
|
+
return { module: candidate.module, name: candidate.name };
|
|
729
|
+
return invalidContract("Resource flow terminal failure is invalid.");
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Checks one canonical qualified declaration reference.
|
|
733
|
+
* @param {unknown} candidate - Candidate reference.
|
|
734
|
+
* @returns {candidate is CanonicalDeclarationReference} Whether the reference is exact.
|
|
735
|
+
*/
|
|
736
|
+
function isDeclarationReference(candidate) {
|
|
737
|
+
return isPlainObject(candidate) && Object.keys(candidate).sort().join(",") == "module,name" &&
|
|
738
|
+
typeof candidate.module == "string" && identityPattern.test(candidate.module) &&
|
|
739
|
+
typeof candidate.name == "string" && declarationNamePattern.test(candidate.name);
|
|
740
|
+
}
|
|
741
|
+
/**
|
|
742
|
+
* Encodes one declaration reference for equality checks.
|
|
743
|
+
* @param {unknown} candidate - Local or qualified reference.
|
|
744
|
+
* @returns {string} Stable equality key.
|
|
745
|
+
*/
|
|
746
|
+
function referenceKey(candidate) {
|
|
747
|
+
return typeof candidate == "string" ? `local:${candidate}` : isDeclarationReference(candidate)
|
|
748
|
+
? `${candidate.module}:${candidate.name}` : `invalid:${String(candidate)}`;
|
|
749
|
+
}
|
|
750
|
+
/**
|
|
751
|
+
* Reports whether a canonical type denotes an owned resource.
|
|
752
|
+
* @param {string | CanonicalDeclarationReference} candidate - Canonical type.
|
|
753
|
+
* @returns {boolean} Whether the type is owned.
|
|
754
|
+
*/
|
|
755
|
+
function isOwnedCanonicalType(candidate) {
|
|
756
|
+
return isDeclarationReference(candidate) || (typeof candidate == "string" && !scalarNames.has(candidate) &&
|
|
757
|
+
!candidate.startsWith("optional:") && candidate != "void");
|
|
758
|
+
}
|
|
759
|
+
/**
|
|
760
|
+
* Validates one closed semantics declaration.
|
|
761
|
+
* @param {unknown} candidate - Candidate semantics.
|
|
762
|
+
* @param {string} operation - Operation name.
|
|
763
|
+
* @returns {Record<string, string>} Closed semantics fields.
|
|
764
|
+
*/
|
|
765
|
+
function validateContractSemantics(candidate, operation) {
|
|
766
|
+
if (!isPlainObject(candidate) || Object.keys(candidate).sort().join(",") !=
|
|
767
|
+
"blocking,close,encoding,eof,newline,ownership,timeout") {
|
|
768
|
+
invalidContract(`Operation '${operation}' requires the closed canonical semantics fields.`);
|
|
769
|
+
}
|
|
770
|
+
/** @type {Record<string, string>} */
|
|
771
|
+
const semantics = {};
|
|
772
|
+
for (const [field, allowed] of Object.entries(semanticsValues)) {
|
|
773
|
+
const value = /** @type {string} */ (candidate[field]);
|
|
774
|
+
if (typeof value != "string" || !allowed.has(value)) {
|
|
775
|
+
invalidContract(`Operation '${operation}' declares a non-canonical '${field}' semantics value.`);
|
|
776
|
+
}
|
|
777
|
+
semantics[field] = value;
|
|
778
|
+
}
|
|
779
|
+
return deepFreeze(semantics);
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Validates one dense ordered single-field named declaration list.
|
|
783
|
+
* @param {unknown} candidate - Candidate list.
|
|
784
|
+
* @param {string} subject - Diagnostic subject.
|
|
785
|
+
* @returns {{name: string}[]} Detached declarations.
|
|
786
|
+
*/
|
|
787
|
+
function validateNamedList(candidate, subject) {
|
|
788
|
+
if (!isDenseArray(candidate))
|
|
789
|
+
invalidContract(`Canonical contract ${subject}s must be a dense array.`);
|
|
790
|
+
const names = new Set();
|
|
791
|
+
/** @type {{name: string}[]} */
|
|
792
|
+
const declarations = [];
|
|
793
|
+
for (const declaration of candidate) {
|
|
794
|
+
if (!isPlainObject(declaration) || Object.keys(declaration).join(",") != "name" ||
|
|
795
|
+
typeof declaration.name != "string" || !declarationNamePattern.test(declaration.name) || names.has(declaration.name)) {
|
|
796
|
+
invalidContract(`Canonical contract ${subject} declarations must be uniquely named.`);
|
|
797
|
+
}
|
|
798
|
+
names.add(/** @type {string} */ (declaration.name));
|
|
799
|
+
declarations.push({ name: /** @type {string} */ (declaration.name) });
|
|
800
|
+
}
|
|
801
|
+
return declarations;
|
|
802
|
+
}
|
|
803
|
+
/**
|
|
804
|
+
* Reports an unknown canonical module identity.
|
|
805
|
+
* @param {string} identity - Unknown identity.
|
|
806
|
+
* @returns {never} Always throws.
|
|
807
|
+
*/
|
|
808
|
+
function unknownModule(identity) {
|
|
809
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_MODULE_UNKNOWN", language: "stdlib",
|
|
810
|
+
message: `Standard-library module '${identity}' is not a registered canonical contract.` });
|
|
811
|
+
}
|
|
812
|
+
/**
|
|
813
|
+
* Reports one malformed version range.
|
|
814
|
+
* @returns {never} Always throws.
|
|
815
|
+
*/
|
|
816
|
+
function malformedRange() {
|
|
817
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_VERSION_MALFORMED", language: "stdlib",
|
|
818
|
+
message: "Standard-library version ranges use X, X.Y, or X.Y.Z without leading zeros or prerelease labels." });
|
|
819
|
+
}
|
|
820
|
+
/**
|
|
821
|
+
* Reports one unsatisfiable version range.
|
|
822
|
+
* @param {string} identity - Constrained module identity.
|
|
823
|
+
* @returns {never} Always throws.
|
|
824
|
+
*/
|
|
825
|
+
function incompatibleVersion(identity) {
|
|
826
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_VERSION_INCOMPATIBLE", language: "stdlib",
|
|
827
|
+
message: `No registered version of '${identity}' satisfies the declared standard-library version range.` });
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* Raises one stable canonical contract diagnostic.
|
|
831
|
+
* @param {string} message - Diagnostic message.
|
|
832
|
+
* @returns {never} Always throws.
|
|
833
|
+
*/
|
|
834
|
+
function invalidContract(message) {
|
|
835
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_CONTRACT_INVALID", language: "stdlib", message });
|
|
836
|
+
}
|
|
837
|
+
/**
|
|
838
|
+
* Requires one exact field set.
|
|
839
|
+
* @param {Record<string, unknown>} value - Candidate object.
|
|
840
|
+
* @param {string[]} keys - Required keys.
|
|
841
|
+
* @param {string} subject - Diagnostic subject.
|
|
842
|
+
* @returns {void}
|
|
843
|
+
*/
|
|
844
|
+
function requireKeys(value, keys, subject) {
|
|
845
|
+
if (Object.keys(value).sort().join(",") != [...keys].sort().join(","))
|
|
846
|
+
invalidContract(`Invalid ${subject} fields.`);
|
|
847
|
+
}
|
|
848
|
+
/**
|
|
849
|
+
* Checks an ordered dense array.
|
|
850
|
+
* @param {unknown} value - Candidate array.
|
|
851
|
+
* @returns {value is unknown[]} Whether the value is dense.
|
|
852
|
+
*/
|
|
853
|
+
function isDenseArray(value) {
|
|
854
|
+
return Array.isArray(value) && value.every((_item, index) => Object.hasOwn(value, index));
|
|
855
|
+
}
|
|
856
|
+
/**
|
|
857
|
+
* Checks for an ordinary string-keyed object.
|
|
858
|
+
* @param {unknown} value - Candidate value.
|
|
859
|
+
* @returns {value is Record<string, unknown>} Whether the value is a plain object.
|
|
860
|
+
*/
|
|
861
|
+
function isPlainObject(value) {
|
|
862
|
+
return value !== null && typeof value == "object" && !Array.isArray(value) &&
|
|
863
|
+
Object.getPrototypeOf(value) == Object.prototype;
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* Recursively freezes a detached value.
|
|
867
|
+
* @template {object} Value
|
|
868
|
+
* @param {Value} value - Object to freeze.
|
|
869
|
+
* @returns {Readonly<Value>} Frozen object.
|
|
870
|
+
*/
|
|
871
|
+
function deepFreeze(value) {
|
|
872
|
+
for (const child of Object.values(value)) {
|
|
873
|
+
if (child && typeof child == "object" && !Object.isFrozen(child))
|
|
874
|
+
deepFreeze(child);
|
|
875
|
+
}
|
|
876
|
+
return Object.freeze(value);
|
|
877
|
+
}
|
|
878
|
+
/** @type {Readonly<StdlibContractRegistry>} */
|
|
879
|
+
const builtinRegistry = createStdlibContractRegistry();
|
|
880
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RkbGliLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NlbWFudGljL3N0ZGxpYi5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFFdEQsTUFBTSxlQUFlLEdBQUcscUJBQXFCLENBQUE7QUFDN0MsTUFBTSxzQkFBc0IsR0FBRywyQkFBMkIsQ0FBQTtBQUMxRCxNQUFNLFdBQVcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQTtBQUM3RCxNQUFNLFNBQVMsR0FBRyxpQkFBaUIsQ0FBQTtBQUNuQyxNQUFNLG1CQUFtQixHQUFHLElBQUksTUFBTSxDQUFDLElBQUksU0FBUyxNQUFNLFNBQVMsTUFBTSxTQUFTLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUMzRixNQUFNLFlBQVksR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLFNBQVMsU0FBUyxTQUFTLFNBQVMsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUM5RSxNQUFNLGVBQWUsR0FBRztJQUN0QixRQUFRLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQztJQUNsQyxLQUFLLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxnQkFBZ0IsRUFBRSx1QkFBdUIsRUFBRSxzQkFBc0IsQ0FBQyxDQUFDO0lBQ25GLEdBQUcsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGdCQUFnQixFQUFFLGNBQWMsQ0FBQyxDQUFDO0lBQ2hELFFBQVEsRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLE9BQU8sRUFBRSxJQUFJLEdBQUcsQ0FBQyxDQUFDLGdCQUFnQixFQUFFLHVCQUF1QixFQUFFLHdCQUF3QixFQUFFLHNCQUFzQixDQUFDLENBQUM7SUFDL0csU0FBUyxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsZ0JBQWdCLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsQ0FBQztJQUMxRSxPQUFPLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQztDQUMzQixDQUFBO0FBRUQsdURBQXVEO0FBQ3ZELGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUU7Ozs7Ozs7Ozs7O0dBV0c7QUFDSDs7Ozs7Ozs7R0FRRztBQUNIOzs7Ozs7Ozs7O0dBVUc7QUFDSDs7OztHQUlHO0FBRUg7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxLQUFLO0lBQ3RDLElBQUksT0FBTyxLQUFLLElBQUksUUFBUSxJQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztRQUFFLE9BQU8sSUFBSSxDQUFBO0lBQzdFLE1BQU0sQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUMxRSxPQUFPLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQTtBQUM5QixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSx1QkFBdUIsQ0FBQyxLQUFLO0lBQzNDLElBQUksT0FBTyxLQUFLLElBQUksUUFBUSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQTtJQUN0RSxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFDMUQsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ3RCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUM3QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFFN0MsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLENBQUM7UUFBRSxPQUFPLEVBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBQyxDQUFBO0lBQzlFLElBQUksS0FBSyxDQUFDLE1BQU0sSUFBSSxDQUFDO1FBQUUsT0FBTyxFQUFDLEtBQUssRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUMsQ0FBQTtJQUN0RixPQUFPLEVBQUMsS0FBSyxFQUFFLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxDQUFDLENBQUMsRUFBQyxDQUFBO0FBQ3pFLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxxQkFBcUIsQ0FBQyxJQUFJLEVBQUUsS0FBSztJQUMvQyxLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMxQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUMsS0FB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LENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxhQUFhLENBQUMsS0FBSztJQUMxQixPQUFPLEtBQUssS0FBSyxJQUFJLElBQUksT0FBTyxLQUFLLElBQUksUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFDeEUsTUFBTSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFBO0FBQ3BELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsVUFBVSxDQUFDLEtBQUs7SUFDdkIsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDekMsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLElBQUksUUFBUSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUM7WUFBRSxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDckYsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQTtBQUM3QixDQUFDO0FBRUQsK0NBQStDO0FBQy9DLE1BQU0sZUFBZSxHQUFHLDRCQUE0QixFQUFFLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtTZW1hbnRpZm9sZERpYWdub3N0aWN9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcblxuY29uc3QgaWRlbnRpdHlQYXR0ZXJuID0gL15bYS16XVthLXowLTkuLV0qJC91XG5jb25zdCBkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuID0gL15bQS1aYS16X11bQS1aYS16MC05X10qJC91XG5jb25zdCBzY2FsYXJOYW1lcyA9IG5ldyBTZXQoW1wiYm9vbGVhblwiLCBcImludGVnZXJcIiwgXCJzdHJpbmdcIl0pXG5jb25zdCBjb21wb25lbnQgPSBcIigwfFsxLTldWzAtOV0qKVwiXG5jb25zdCBleGFjdFZlcnNpb25QYXR0ZXJuID0gbmV3IFJlZ0V4cChgXiR7Y29tcG9uZW50fVxcXFwuJHtjb21wb25lbnR9XFxcXC4ke2NvbXBvbmVudH0kYCwgXCJ1XCIpXG5jb25zdCByYW5nZVBhdHRlcm4gPSBuZXcgUmVnRXhwKGBeJHtjb21wb25lbnR9KD86XFxcXC4ke2NvbXBvbmVudH0pezAsMn0kYCwgXCJ1XCIpXG5jb25zdCBzZW1hbnRpY3NWYWx1ZXMgPSB7XG4gIGJsb2NraW5nOiBuZXcgU2V0KFtcInN5bmNocm9ub3VzXCJdKSxcbiAgY2xvc2U6IG5ldyBTZXQoW1wibm90LWFwcGxpY2FibGVcIiwgXCJ1c2UtYWZ0ZXItY2xvc2UtZmFpbHNcIiwgXCJyZXBlYXRlZC1jbG9zZS1mYWlsc1wiXSksXG4gIGVvZjogbmV3IFNldChbXCJub3QtYXBwbGljYWJsZVwiLCBcImFic2VudC12YWx1ZVwiXSksXG4gIGVuY29kaW5nOiBuZXcgU2V0KFtcIm5vdC1hcHBsaWNhYmxlXCIsIFwidXRmLThcIl0pLFxuICBuZXdsaW5lOiBuZXcgU2V0KFtcIm5vdC1hcHBsaWNhYmxlXCIsIFwic3RyaXAtbGluZS10ZXJtaW5hdG9yXCIsIFwicmV0YWluLWxpbmUtdGVybWluYXRvclwiLCBcImFwcGVuZC1sZi1pZi1taXNzaW5nXCJdKSxcbiAgb3duZXJzaGlwOiBuZXcgU2V0KFtcIm5vdC1hcHBsaWNhYmxlXCIsIFwiYWNxdWlyZWRcIiwgXCJib3Jyb3dlZFwiLCBcImNvbnN1bWVkXCJdKSxcbiAgdGltZW91dDogbmV3IFNldChbXCJub25lXCJdKVxufVxuXG4vKiogQHR5cGVkZWYge1tudW1iZXIsIG51bWJlciwgbnVtYmVyXX0gVmVyc2lvblR1cGxlICovXG4vKiogQHR5cGVkZWYge3tsb3dlcjogVmVyc2lvblR1cGxlLCB1cHBlcjogVmVyc2lvblR1cGxlIHwgbnVsbH19IFZlcnNpb25SYW5nZSAqL1xuLyoqIEB0eXBlZGVmIHt7bW9kdWxlOiBzdHJpbmcsIG5hbWU6IHN0cmluZ319IENhbm9uaWNhbERlY2xhcmF0aW9uUmVmZXJlbmNlICovXG4vKipcbiAqIEB0eXBlZGVmIFN0ZGxpYkNvbnRyYWN0T3BlcmF0aW9uXG4gKiBAcHJvcGVydHkge3ttb2R1bGU6IHN0cmluZywgb3BlcmF0aW9uOiBzdHJpbmcsIHJhbmdlOiBWZXJzaW9uUmFuZ2V9W119IGRlcGVuZGVuY2llcyAtIENhbm9uaWNhbCBvcGVyYXRpb24gZGVwZW5kZW5jaWVzLlxuICogQHByb3BlcnR5IHtbXCJob3N0XCJdfSBlZmZlY3RzIC0gQ2xvc2VkIGVmZmVjdCBkZWNsYXJhdGlvbi5cbiAqIEBwcm9wZXJ0eSB7XCJsZWZ0LXRvLXJpZ2h0XCJ9IGV2YWx1YXRpb25PcmRlciAtIENhbm9uaWNhbCBhcmd1bWVudCBldmFsdWF0aW9uIG9yZGVyLlxuICogQHByb3BlcnR5IHsoc3RyaW5nIHwgQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2UpW119IGZhaWx1cmVzIC0gRGVjbGFyZWQgZmFpbHVyZSBuYW1lcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBuYW1lIC0gT3BlcmF0aW9uIG5hbWUuXG4gKiBAcHJvcGVydHkge3tuYW1lOiBzdHJpbmcsIHR5cGU6IHN0cmluZyB8IENhbm9uaWNhbERlY2xhcmF0aW9uUmVmZXJlbmNlfVtdfSBwYXJhbWV0ZXJzIC0gT3JkZXJlZCBwYXJhbWV0ZXJzLlxuICogQHByb3BlcnR5IHtvYmplY3R9IHJlc291cmNlRmxvdyAtIENsb3NlZCByZXNvdXJjZSB0cmFuc2l0aW9uLlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBDYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gcmV0dXJuVHlwZSAtIENsb3NlZCByZXR1cm4gdHlwZSBzcGVsbGluZy5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gc2VtYW50aWNzIC0gQ2xvc2VkIGNhbm9uaWNhbCBzZW1hbnRpY3MgZmllbGRzLlxuICovXG4vKipcbiAqIEB0eXBlZGVmIFN0ZGxpYkNvbnRyYWN0TW9kdWxlXG4gKiBAcHJvcGVydHkge3ttb2R1bGU6IHN0cmluZywgcmFuZ2U6IFZlcnNpb25SYW5nZX1bXX0gZGVwZW5kZW5jaWVzIC0gVmVyc2lvbmVkIGRlY2xhcmF0aW9uIGRlcGVuZGVuY2llcy5cbiAqIEBwcm9wZXJ0eSB7e25hbWU6IHN0cmluZ31bXX0gZmFpbHVyZXMgLSBPcmRlcmVkIGZhaWx1cmUgZGVjbGFyYXRpb25zLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IGlkZW50aXR5IC0gQ2Fub25pY2FsIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7U3RkbGliQ29udHJhY3RPcGVyYXRpb25bXX0gb3BlcmF0aW9ucyAtIE9yZGVyZWQgb3BlcmF0aW9uIGRlY2xhcmF0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7e25hbWU6IHN0cmluZ31bXX0gcmVzb3VyY2VzIC0gT3JkZXJlZCByZXNvdXJjZSBkZWNsYXJhdGlvbnMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdmVyc2lvbiAtIEV4YWN0IHJlZ2lzdGVyZWQgdmVyc2lvbi5cbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiBTdGRsaWJDb250cmFjdFxuICogQHByb3BlcnR5IHt7bW9kdWxlOiBzdHJpbmcsIHJhbmdlOiBWZXJzaW9uUmFuZ2V9W119IGRlcGVuZGVuY2llcyAtIFZlcnNpb25lZCBkZWNsYXJhdGlvbiBkZXBlbmRlbmNpZXMuXG4gKiBAcHJvcGVydHkge3tuYW1lOiBzdHJpbmd9W119IGZhaWx1cmVzIC0gT3JkZXJlZCBmYWlsdXJlIGRlY2xhcmF0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBpZGVudGl0eSAtIENhbm9uaWNhbCBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge1N0ZGxpYkNvbnRyYWN0T3BlcmF0aW9uW119IG9wZXJhdGlvbnMgLSBPcmRlcmVkIG9wZXJhdGlvbiBkZWNsYXJhdGlvbnMuXG4gKiBAcHJvcGVydHkge3tuYW1lOiBzdHJpbmd9W119IHJlc291cmNlcyAtIE9yZGVyZWQgcmVzb3VyY2UgZGVjbGFyYXRpb25zLlxuICogQHByb3BlcnR5IHtcIlNlbWFudGlmb2xkU3RkbGliQ29udHJhY3RcIn0gc2NoZW1hIC0gQ29udHJhY3Qgc2NoZW1hIGRpc2NyaW1pbmF0b3IuXG4gKiBAcHJvcGVydHkgezF9IHNjaGVtYVZlcnNpb24gLSBDb250cmFjdCBzY2hlbWEgdmVyc2lvbi5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSB2ZXJzaW9uIC0gUmVzb2x2ZWQgZXhhY3QgdmVyc2lvbi5cbiAqL1xuLyoqXG4gKiBAdHlwZWRlZiBTdGRsaWJDb250cmFjdFJlZ2lzdHJ5XG4gKiBAcHJvcGVydHkge3tpZGVudGl0eTogc3RyaW5nLCB2ZXJzaW9uczogc3RyaW5nW119W119IG1vZHVsZXMgLSBSZWdpc3RlcmVkIG1vZHVsZXMgaW4gc3RhYmxlIG9yZGVyLlxuICogQHByb3BlcnR5IHsoaWRlbnRpdHk6IHN0cmluZywgcmFuZ2U/OiBzdHJpbmcpID0+IFN0ZGxpYkNvbnRyYWN0fSByZXNvbHZlTW9kdWxlIC0gVmVyc2lvbmVkIG1vZHVsZSByZXNvbHV0aW9uLlxuICovXG5cbi8qKlxuICogUGFyc2VzIG9uZSBleGFjdCBYLlkuWiBzdGFuZGFyZC1saWJyYXJ5IHZlcnNpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHZlcnNpb24uXG4gKiBAcmV0dXJucyB7VmVyc2lvblR1cGxlIHwgbnVsbH0gUGFyc2VkIHZlcnNpb24gb3IgbnVsbCB3aGVuIG1hbGZvcm1lZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlU3RkbGliVmVyc2lvbih2YWx1ZSkge1xuICBpZiAodHlwZW9mIHZhbHVlICE9IFwic3RyaW5nXCIgfHwgIWV4YWN0VmVyc2lvblBhdHRlcm4udGVzdCh2YWx1ZSkpIHJldHVybiBudWxsXG4gIGNvbnN0IFttYWpvciwgbWlub3IsIHBhdGNoXSA9IHZhbHVlLnNwbGl0KFwiLlwiKS5tYXAoKHBhcnQpID0+IE51bWJlcihwYXJ0KSlcbiAgcmV0dXJuIFttYWpvciwgbWlub3IsIHBhdGNoXVxufVxuXG4vKipcbiAqIFBhcnNlcyBvbmUgWCwgWC5ZLCBvciBYLlkuWiBzdGFuZGFyZC1saWJyYXJ5IHZlcnNpb24gcmFuZ2UuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHJhbmdlLlxuICogQHJldHVybnMge1ZlcnNpb25SYW5nZSB8IG51bGx9IEhhbGYtb3BlbiByYW5nZSBvciBudWxsIHdoZW4gbWFsZm9ybWVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UodmFsdWUpIHtcbiAgaWYgKHR5cGVvZiB2YWx1ZSAhPSBcInN0cmluZ1wiIHx8ICFyYW5nZVBhdHRlcm4udGVzdCh2YWx1ZSkpIHJldHVybiBudWxsXG4gIGNvbnN0IHBhcnRzID0gdmFsdWUuc3BsaXQoXCIuXCIpLm1hcCgocGFydCkgPT4gTnVtYmVyKHBhcnQpKVxuICBjb25zdCBtYWpvciA9IHBhcnRzWzBdXG4gIGNvbnN0IG1pbm9yID0gcGFydHMubGVuZ3RoID4gMSA/IHBhcnRzWzFdIDogMFxuICBjb25zdCBwYXRjaCA9IHBhcnRzLmxlbmd0aCA+IDIgPyBwYXJ0c1syXSA6IDBcblxuICBpZiAocGFydHMubGVuZ3RoID09IDEpIHJldHVybiB7bG93ZXI6IFttYWpvciwgMCwgMF0sIHVwcGVyOiBbbWFqb3IgKyAxLCAwLCAwXX1cbiAgaWYgKHBhcnRzLmxlbmd0aCA9PSAyKSByZXR1cm4ge2xvd2VyOiBbbWFqb3IsIG1pbm9yLCAwXSwgdXBwZXI6IFttYWpvciwgbWlub3IgKyAxLCAwXX1cbiAgcmV0dXJuIHtsb3dlcjogW21ham9yLCBtaW5vciwgcGF0Y2hdLCB1cHBlcjogW21ham9yLCBtaW5vciwgcGF0Y2ggKyAxXX1cbn1cblxuLyoqXG4gKiBDb21wYXJlcyB0d28gZXhhY3QgdmVyc2lvbiB0dXBsZXMuXG4gKiBAcGFyYW0ge1ZlcnNpb25UdXBsZX0gbGVmdCAtIExlZnQgdmVyc2lvbi5cbiAqIEBwYXJhbSB7VmVyc2lvblR1cGxlfSByaWdodCAtIFJpZ2h0IHZlcnNpb24uXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBOZWdhdGl2ZSwgemVybywgb3IgcG9zaXRpdmUgb3JkZXJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wYXJlU3RkbGliVmVyc2lvbnMobGVmdCwgcmlnaHQpIHtcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IDM7IGluZGV4ICs9IDEpIHtcbiAgICBpZiAobGVmdFtpbmRleF0gIT0gcmlnaHRbaW5kZXhdKSByZXR1cm4gbGVmdFtpbmRleF0gPCByaWdodFtpbmRleF0gPyAtMSA6IDFcbiAgfVxuICByZXR1cm4gMFxufVxuXG4vKipcbiAqIERlcml2ZXMgb25lIHByb3RlY3RlZCBuYXRpdmUgcHJvdmlkZXIgZW50cnkgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXQgLSBBZG9wdGVkIHByb3ZpZGVyIHRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGUgLSBMZWdhY3kgb3BlcmF0aW9uIG5hbWUgb3IgY2Fub25pY2FsIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3BlcmF0aW9uXSAtIFF1YWxpZmllZCBjYW5vbmljYWwgb3BlcmF0aW9uIG5hbWUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBQcm90ZWN0ZWQgbmF0aXZlIGVudHJ5IG5hbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm90ZWN0ZWRFbnRyeU5hbWUodGFyZ2V0LCBtb2R1bGUsIG9wZXJhdGlvbikge1xuICBpZiAodHlwZW9mIHRhcmdldCAhPSBcInN0cmluZ1wiIHx8ICEvXlthLXpdW2EtejAtOS1dKiQvdS50ZXN0KHRhcmdldCkgfHxcbiAgICB0eXBlb2YgbW9kdWxlICE9IFwic3RyaW5nXCIgfHwgKG9wZXJhdGlvbiAhPT0gdW5kZWZpbmVkICYmICh0eXBlb2Ygb3BlcmF0aW9uICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICFkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3Qob3BlcmF0aW9uKSkpKSBpbnZhbGlkQ29udHJhY3QoXCJQcm90ZWN0ZWQgcHJvdmlkZXIgZW50cnkgY29tcG9uZW50cyBhcmUgaW52YWxpZC5cIilcbiAgaWYgKG9wZXJhdGlvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3QobW9kdWxlKSkgaW52YWxpZENvbnRyYWN0KFwiUHJvdGVjdGVkIHByb3ZpZGVyIG9wZXJhdGlvbiBuYW1lIGlzIGludmFsaWQuXCIpXG4gICAgcmV0dXJuIGBfX3NlbWFudGlmb2xkX3Byb3ZpZGVyXyR7dGFyZ2V0fV8ke21vZHVsZX1gXG4gIH1cbiAgaWYgKCFpZGVudGl0eVBhdHRlcm4udGVzdChtb2R1bGUpKSBpbnZhbGlkQ29udHJhY3QoXCJQcm90ZWN0ZWQgcHJvdmlkZXIgbW9kdWxlIGlkZW50aXR5IGlzIGludmFsaWQuXCIpXG4gIGNvbnN0IGVuY29kZWRNb2R1bGUgPSBbLi4ubW9kdWxlXS5tYXAoKGNoYXJhY3RlcikgPT4gY2hhcmFjdGVyLmNoYXJDb2RlQXQoMCkudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIFwiMFwiKSkuam9pbihcIlwiKVxuXG4gIHJldHVybiBgX19zZW1hbnRpZm9sZF9wcm92aWRlcl8ke3RhcmdldH1fbSR7ZW5jb2RlZE1vZHVsZS5sZW5ndGh9XyR7ZW5jb2RlZE1vZHVsZX1fJHtvcGVyYXRpb259YFxufVxuXG4vKipcbiAqIFBhcnNlcyBvbmUgcHJvdGVjdGVkIG5hdGl2ZSBwcm92aWRlciBlbnRyeSBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBDYW5kaWRhdGUgcHJvdGVjdGVkIGVudHJ5IG5hbWUuXG4gKiBAcmV0dXJucyB7e3RhcmdldDogc3RyaW5nLCBtb2R1bGU/OiBzdHJpbmcsIG9wZXJhdGlvbjogc3RyaW5nfSB8IG51bGx9IFBhcnNlZCBiaW5kaW5nIG9yIG51bGwgd2hlbiB1bnBhcnNlYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUHJvdGVjdGVkRW50cnlOYW1lKG5hbWUpIHtcbiAgY29uc3QgcXVhbGlmaWVkID0gL15fX3NlbWFudGlmb2xkX3Byb3ZpZGVyXyhbYS16XVthLXowLTktXSopX20oWzAtOV0rKV8oWzAtOWEtZl0rKV8oW0EtWmEtel9dW0EtWmEtejAtOV9dKikkL3UuZXhlYyhuYW1lKVxuXG4gIGlmIChxdWFsaWZpZWQpIHtcbiAgICBjb25zdCBlbmNvZGVkTGVuZ3RoID0gTnVtYmVyKHF1YWxpZmllZFsyXSlcbiAgICBjb25zdCBlbmNvZGVkID0gcXVhbGlmaWVkWzNdXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGVuY29kZWRMZW5ndGgpIHx8IGVuY29kZWRMZW5ndGggIT0gZW5jb2RlZC5sZW5ndGggfHwgZW5jb2RlZC5sZW5ndGggJSAyICE9IDApIHJldHVybiBudWxsXG4gICAgbGV0IG1vZHVsZSA9IFwiXCJcblxuICAgIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBlbmNvZGVkLmxlbmd0aDsgaW5kZXggKz0gMikgbW9kdWxlICs9IFN0cmluZy5mcm9tQ2hhckNvZGUoTnVtYmVyLnBhcnNlSW50KGVuY29kZWQuc2xpY2UoaW5kZXgsIGluZGV4ICsgMiksIDE2KSlcbiAgICBpZiAoIWlkZW50aXR5UGF0dGVybi50ZXN0KG1vZHVsZSkgfHwgcHJvdGVjdGVkRW50cnlOYW1lKHF1YWxpZmllZFsxXSwgbW9kdWxlLCBxdWFsaWZpZWRbNF0pICE9IG5hbWUpIHJldHVybiBudWxsXG4gICAgcmV0dXJuIHttb2R1bGUsIG9wZXJhdGlvbjogcXVhbGlmaWVkWzRdLCB0YXJnZXQ6IHF1YWxpZmllZFsxXX1cbiAgfVxuICBjb25zdCBtYXRjaCA9IC9eX19zZW1hbnRpZm9sZF9wcm92aWRlcl8oW2Etel1bYS16MC05LV0qKV8oLispJC91LmV4ZWMobmFtZSlcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIG51bGxcbiAgcmV0dXJuIHtvcGVyYXRpb246IG1hdGNoWzJdLCB0YXJnZXQ6IG1hdGNoWzFdfVxufVxuXG4vKipcbiAqIEludGVyc2VjdHMgdHdvIGhhbGYtb3BlbiB2ZXJzaW9uIHJhbmdlcy5cbiAqIEBwYXJhbSB7VmVyc2lvblJhbmdlfSBsZWZ0IC0gTGVmdCByYW5nZS5cbiAqIEBwYXJhbSB7VmVyc2lvblJhbmdlfSByaWdodCAtIFJpZ2h0IHJhbmdlLlxuICogQHJldHVybnMge1ZlcnNpb25SYW5nZSB8IG51bGx9IEludGVyc2VjdGlvbiBvciBudWxsIHdoZW4gZW1wdHkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnRlcnNlY3RTdGRsaWJWZXJzaW9uUmFuZ2VzKGxlZnQsIHJpZ2h0KSB7XG4gIGNvbnN0IGxvd2VyID0gY29tcGFyZVN0ZGxpYlZlcnNpb25zKGxlZnQubG93ZXIsIHJpZ2h0Lmxvd2VyKSA+PSAwID8gbGVmdC5sb3dlciA6IHJpZ2h0Lmxvd2VyXG4gIGNvbnN0IHVwcGVyID0gbGVmdC51cHBlciA9PT0gbnVsbCA/IHJpZ2h0LnVwcGVyIDogcmlnaHQudXBwZXIgPT09IG51bGwgPyBsZWZ0LnVwcGVyIDpcbiAgICBjb21wYXJlU3RkbGliVmVyc2lvbnMobGVmdC51cHBlciwgcmlnaHQudXBwZXIpIDw9IDAgPyBsZWZ0LnVwcGVyIDogcmlnaHQudXBwZXJcblxuICBpZiAodXBwZXIgIT09IG51bGwgJiYgY29tcGFyZVN0ZGxpYlZlcnNpb25zKGxvd2VyLCB1cHBlcikgPj0gMCkgcmV0dXJuIG51bGxcbiAgcmV0dXJuIHtsb3dlciwgdXBwZXJ9XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgb25lIGV4YWN0IHZlcnNpb24gc2F0aXNmaWVzIG9uZSBoYWxmLW9wZW4gcmFuZ2UuXG4gKiBAcGFyYW0ge1ZlcnNpb25UdXBsZX0gdmVyc2lvbiAtIENhbmRpZGF0ZSB2ZXJzaW9uLlxuICogQHBhcmFtIHtWZXJzaW9uUmFuZ2V9IHJhbmdlIC0gRGVjbGFyZWQgcmFuZ2UuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgdmVyc2lvbiBzYXRpc2ZpZXMgdGhlIHJhbmdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RkbGliVmVyc2lvblNhdGlzZmllcyh2ZXJzaW9uLCByYW5nZSkge1xuICBpZiAoY29tcGFyZVN0ZGxpYlZlcnNpb25zKHZlcnNpb24sIHJhbmdlLmxvd2VyKSA8IDApIHJldHVybiBmYWxzZVxuICByZXR1cm4gcmFuZ2UudXBwZXIgPT09IG51bGwgfHwgY29tcGFyZVN0ZGxpYlZlcnNpb25zKHZlcnNpb24sIHJhbmdlLnVwcGVyKSA8IDBcbn1cblxuLyoqXG4gKiBDcmVhdGVzIHRoZSBidWlsdC1pbiB2ZXJzaW9uZWQgY2Fub25pY2FsIHN0ZGxpYiBjb250cmFjdCByZWdpc3RyeS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gcmVjb3JkcyAtIE9wdGlvbmFsIG92ZXJyaWRlIHJlY29yZCBzZXQ7IGJ1aWx0LWluIHByb2JlIGNvbnRyYWN0IGJ5IGRlZmF1bHQuXG4gKiBAcmV0dXJucyB7UmVhZG9ubHk8U3RkbGliQ29udHJhY3RSZWdpc3RyeT59IEZyb3plbiByZWdpc3RyeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVN0ZGxpYkNvbnRyYWN0UmVnaXN0cnkocmVjb3JkcyA9IGJ1aWx0aW5Db250cmFjdHMoKSkge1xuICBpZiAoIWlzRGVuc2VBcnJheShyZWNvcmRzKSkgaW52YWxpZENvbnRyYWN0KFwiQ2Fub25pY2FsIGNvbnRyYWN0IHJlY29yZHMgbXVzdCBiZSBhbiBvcmRlcmVkIGRlbnNlIGFycmF5LlwiKVxuXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgTWFwPHN0cmluZywgU3RkbGliQ29udHJhY3RNb2R1bGU+Pn0gKi9cbiAgY29uc3QgbW9kdWxlcyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIHJlY29yZHMpIHtcbiAgICBjb25zdCByZWNvcmQgPSB2YWxpZGF0ZUNvbnRyYWN0UmVjb3JkKGNhbmRpZGF0ZSlcbiAgICBjb25zdCB2ZXJzaW9ucyA9IG1vZHVsZXMuZ2V0KHJlY29yZC5pZGVudGl0eSkgPz8gbmV3IE1hcCgpXG5cbiAgICBpZiAodmVyc2lvbnMuaGFzKHJlY29yZC52ZXJzaW9uKSkgaW52YWxpZENvbnRyYWN0KGBEdXBsaWNhdGUgY2Fub25pY2FsIGNvbnRyYWN0ICcke3JlY29yZC5pZGVudGl0eX0nIHZlcnNpb24gJyR7cmVjb3JkLnZlcnNpb259Jy5gKVxuICAgIHZlcnNpb25zLnNldChyZWNvcmQudmVyc2lvbiwgcmVjb3JkKVxuICAgIG1vZHVsZXMuc2V0KHJlY29yZC5pZGVudGl0eSwgdmVyc2lvbnMpXG4gIH1cbiAgZm9yIChjb25zdCByZWNvcmQgb2YgbW9kdWxlcy52YWx1ZXMoKSkge1xuICAgIGZvciAoY29uc3QgbW9kdWxlIG9mIHJlY29yZC52YWx1ZXMoKSkgdmFsaWRhdGVDb250cmFjdERlcGVuZGVuY2llcyhtb2R1bGUsIG1vZHVsZXMpXG4gIH1cbiAgY29uc3QgZnJvemVuTW9kdWxlcyA9IFsuLi5tb2R1bGVzLmVudHJpZXMoKV1cbiAgICAubWFwKChbaWRlbnRpdHksIHZlcnNpb25zXSkgPT4gKHtcbiAgICAgIGlkZW50aXR5LFxuICAgICAgdmVyc2lvbnM6IFsuLi52ZXJzaW9ucy5rZXlzKCldLm1hcCgodmVyc2lvbikgPT4gLyoqIEB0eXBlIHtWZXJzaW9uVHVwbGV9ICovIChwYXJzZVN0ZGxpYlZlcnNpb24odmVyc2lvbikpKVxuICAgICAgICAuc29ydChjb21wYXJlU3RkbGliVmVyc2lvbnMpXG4gICAgICAgIC5tYXAoKFttYWpvciwgbWlub3IsIHBhdGNoXSkgPT4gYCR7bWFqb3J9LiR7bWlub3J9LiR7cGF0Y2h9YClcbiAgICB9KSlcbiAgICAubWFwKGRlZXBGcmVlemUpXG4gIGNvbnN0IHN0b3JlID0gZGVlcEZyZWV6ZSgvKiogQHR5cGUge3ttb2R1bGVzOiBbc3RyaW5nLCBSZWFkb25seTxNYXA8c3RyaW5nLCBSZWFkb25seTxTdGRsaWJDb250cmFjdE1vZHVsZT4+Pl1bXX19ICovICh7XG4gICAgbW9kdWxlczogWy4uLm1vZHVsZXMuZW50cmllcygpXS5tYXAoKFtpZGVudGl0eSwgdmVyc2lvbnNdKSA9PiBbaWRlbnRpdHksIGRlZXBGcmVlemUodmVyc2lvbnMpXSlcbiAgfSkpXG4gIHJldHVybiBPYmplY3QuZnJlZXplKC8qKiBAdHlwZSB7U3RkbGliQ29udHJhY3RSZWdpc3RyeX0gKi8gKHtcbiAgICBtb2R1bGVzOiBPYmplY3QuZnJlZXplKGZyb3plbk1vZHVsZXMpLFxuICAgIHJlc29sdmVNb2R1bGUoaWRlbnRpdHksIHJhbmdlKSB7XG4gICAgICByZXR1cm4gcmVzb2x2ZVJlZ2lzdHJ5TW9kdWxlKHN0b3JlLCBpZGVudGl0eSwgcmFuZ2UpXG4gICAgfVxuICB9KSlcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgbW9kdWxlIGlkZW50aXR5IHBsdXMgb3B0aW9uYWwgcmFuZ2UgYWdhaW5zdCBvbmUgcmVnaXN0cnkgc3RvcmUuXG4gKiBAcGFyYW0ge3ttb2R1bGVzOiBbc3RyaW5nLCBSZWFkb25seTxNYXA8c3RyaW5nLCBSZWFkb25seTxTdGRsaWJDb250cmFjdE1vZHVsZT4+Pl1bXX19IHN0b3JlIC0gUmVnaXN0cnkgc3RvcmUuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHkgLSBDYW5vbmljYWwgbW9kdWxlIGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IFtyYW5nZV0gLSBEZWNsYXJlZCB2ZXJzaW9uIHJhbmdlLlxuICogQHJldHVybnMge1N0ZGxpYkNvbnRyYWN0fSBEZXRhY2hlZCBmcm96ZW4gY29udHJhY3QuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVSZWdpc3RyeU1vZHVsZShzdG9yZSwgaWRlbnRpdHksIHJhbmdlKSB7XG4gIGNvbnN0IHZlcnNpb25zID0gc3RvcmUubW9kdWxlcy5maW5kKChbY2FuZGlkYXRlXSkgPT4gY2FuZGlkYXRlID09IGlkZW50aXR5KT8uWzFdXG5cbiAgaWYgKCF2ZXJzaW9ucykgdW5rbm93bk1vZHVsZShpZGVudGl0eSlcbiAgY29uc3QgcGFyc2VkID0gcmFuZ2UgPT09IHVuZGVmaW5lZCA/IC8qKiBAdHlwZSB7VmVyc2lvblJhbmdlfSAqLyAoe2xvd2VyOiBbMCwgMCwgMF0sIHVwcGVyOiBudWxsfSkgOiBwYXJzZVN0ZGxpYlZlcnNpb25SYW5nZShyYW5nZSlcblxuICBpZiAoIXBhcnNlZCkgbWFsZm9ybWVkUmFuZ2UoKVxuICAvKiogQHR5cGUge1ZlcnNpb25UdXBsZSB8IHVuZGVmaW5lZH0gKi9cbiAgbGV0IHJlc29sdmVkXG5cbiAgZm9yIChjb25zdCB2ZXJzaW9uIG9mIHZlcnNpb25zLmtleXMoKSkge1xuICAgIGNvbnN0IHR1cGxlID0gLyoqIEB0eXBlIHtWZXJzaW9uVHVwbGV9ICovIChwYXJzZVN0ZGxpYlZlcnNpb24odmVyc2lvbikpXG5cbiAgICBpZiAoc3RkbGliVmVyc2lvblNhdGlzZmllcyh0dXBsZSwgcGFyc2VkKSAmJiAocmVzb2x2ZWQgPT09IHVuZGVmaW5lZCB8fCBjb21wYXJlU3RkbGliVmVyc2lvbnModHVwbGUsIHJlc29sdmVkKSA+IDApKSB7XG4gICAgICByZXNvbHZlZCA9IHR1cGxlXG4gICAgfVxuICB9XG4gIGlmIChyZXNvbHZlZCA9PT0gdW5kZWZpbmVkKSBpbmNvbXBhdGlibGVWZXJzaW9uKGlkZW50aXR5KVxuICBjb25zdCByZWNvcmQgPSAvKiogQHR5cGUge1JlYWRvbmx5PFN0ZGxpYkNvbnRyYWN0TW9kdWxlPn0gKi8gKHZlcnNpb25zLmdldChgJHtyZXNvbHZlZFswXX0uJHtyZXNvbHZlZFsxXX0uJHtyZXNvbHZlZFsyXX1gKSlcblxuICByZXR1cm4gZGVlcEZyZWV6ZSh7XG4gICAgZGVwZW5kZW5jaWVzOiByZWNvcmQuZGVwZW5kZW5jaWVzLFxuICAgIGZhaWx1cmVzOiByZWNvcmQuZmFpbHVyZXMsXG4gICAgaWRlbnRpdHk6IHJlY29yZC5pZGVudGl0eSxcbiAgICBvcGVyYXRpb25zOiByZWNvcmQub3BlcmF0aW9ucyxcbiAgICByZXNvdXJjZXM6IHJlY29yZC5yZXNvdXJjZXMsXG4gICAgc2NoZW1hOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTZW1hbnRpZm9sZFN0ZGxpYkNvbnRyYWN0XCIpLFxuICAgIHNjaGVtYVZlcnNpb246IC8qKiBAdHlwZSB7Y29uc3R9ICovICgxKSxcbiAgICB2ZXJzaW9uOiBgJHtyZXNvbHZlZFswXX0uJHtyZXNvbHZlZFsxXX0uJHtyZXNvbHZlZFsyXX1gXG4gIH0pXG59XG5cbi8qKlxuICogTGlzdHMgdGhlIGJ1aWx0LWluIGNhbm9uaWNhbCBzdGRsaWIgbW9kdWxlcyB3aXRoIHRoZWlyIHJlZ2lzdGVyZWQgdmVyc2lvbnMuXG4gKiBAcmV0dXJucyB7UmVhZG9ubHk8e2lkZW50aXR5OiBzdHJpbmcsIHZlcnNpb25zOiBzdHJpbmdbXX1bXT59IEZyb3plbiBtb2R1bGUgbGlzdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxpc3RTdGRsaWJNb2R1bGVzKCkge1xuICByZXR1cm4gYnVpbHRpblJlZ2lzdHJ5Lm1vZHVsZXNcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgYnVpbHQtaW4gY2Fub25pY2FsIHN0ZGxpYiBtb2R1bGUgYnkgaWRlbnRpdHkgYW5kIG9wdGlvbmFsIHJhbmdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkZW50aXR5IC0gQ2Fub25pY2FsIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcmFuZ2VdIC0gRGVjbGFyZWQgdmVyc2lvbiByYW5nZS5cbiAqIEByZXR1cm5zIHtTdGRsaWJDb250cmFjdH0gRGV0YWNoZWQgZnJvemVuIGNvbnRyYWN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVN0ZGxpYk1vZHVsZShpZGVudGl0eSwgcmFuZ2UpIHtcbiAgcmV0dXJuIGJ1aWx0aW5SZWdpc3RyeS5yZXNvbHZlTW9kdWxlKGlkZW50aXR5LCByYW5nZSlcbn1cblxuLyoqXG4gKiBEZWNsYXJlcyB0aGUgYnVpbHQtaW4gVGFzayAwMzQgcmVzb3VyY2UtcHJvYmUgY2Fub25pY2FsIGNvbnRyYWN0LlxuICogQHJldHVybnMge3Vua25vd259IFVudmFsaWRhdGVkIGJ1aWx0LWluIHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gYnVpbHRpblByb2JlQ29udHJhY3QoKSB7XG4gIHJldHVybiB7XG4gICAgZGVwZW5kZW5jaWVzOiBbXSxcbiAgICBmYWlsdXJlczogW1xuICAgICAge25hbWU6IFwiUHJvYmVPcGVyYXRpb25GYWlsdXJlXCJ9LFxuICAgICAge25hbWU6IFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwifSxcbiAgICAgIHtuYW1lOiBcIlByb2JlUmVhZEZhaWx1cmVcIn0sXG4gICAgICB7bmFtZTogXCJQcm9iZUNsb3NlRmFpbHVyZVwifSxcbiAgICAgIHtuYW1lOiBcIlByb2JlUmVzb3VyY2VDbG9zZWRcIn1cbiAgICBdLFxuICAgIGlkZW50aXR5OiBcInNlbWFudGlmb2xkLnRhc2swMzQucmVzb3VyY2UtcHJvYmVcIixcbiAgICBvcGVyYXRpb25zOiBbXG4gICAgICB7XG4gICAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgICAgIGVmZmVjdHM6IFtcImhvc3RcIl0sXG4gICAgICAgIGV2YWx1YXRpb25PcmRlcjogXCJsZWZ0LXRvLXJpZ2h0XCIsXG4gICAgICAgIGZhaWx1cmVzOiBbXCJQcm9iZU9wZXJhdGlvbkZhaWx1cmVcIl0sXG4gICAgICAgIG5hbWU6IFwicHJvYmVFZmZlY3RcIixcbiAgICAgICAgcGFyYW1ldGVyczogW3tuYW1lOiBcImxhYmVsXCIsIHR5cGU6IFwic3RyaW5nXCJ9LCB7bmFtZTogXCJ2YWx1ZVwiLCB0eXBlOiBcImludGVnZXJcIn0sIHtuYW1lOiBcImZhaWxcIiwgdHlwZTogXCJib29sZWFuXCJ9XSxcbiAgICAgICAgcmVzb3VyY2VGbG93OiB7a2luZDogXCJub25lXCJ9LFxuICAgICAgICByZXR1cm5UeXBlOiBcImludGVnZXJcIixcbiAgICAgICAgc2VtYW50aWNzOiBjYW5vbmljYWxTZW1hbnRpY3MoKVxuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAgZGVwZW5kZW5jaWVzOiBbXSxcbiAgICAgICAgZWZmZWN0czogW1wiaG9zdFwiXSxcbiAgICAgICAgZXZhbHVhdGlvbk9yZGVyOiBcImxlZnQtdG8tcmlnaHRcIixcbiAgICAgICAgZmFpbHVyZXM6IFtcIlByb2JlQWNxdWlyZUZhaWx1cmVcIl0sXG4gICAgICAgIG5hbWU6IFwicHJvYmVBY3F1aXJlXCIsXG4gICAgICAgIHBhcmFtZXRlcnM6IFt7bmFtZTogXCJmYWlsXCIsIHR5cGU6IFwiYm9vbGVhblwifV0sXG4gICAgICAgIHJlc291cmNlRmxvdzoge2tpbmQ6IFwiYWNxdWlyZVwiLCByZXNvdXJjZTogXCJQcm9iZVJlc291cmNlXCJ9LFxuICAgICAgICByZXR1cm5UeXBlOiBcIlByb2JlUmVzb3VyY2VcIixcbiAgICAgICAgc2VtYW50aWNzOiBjYW5vbmljYWxTZW1hbnRpY3Moe293bmVyc2hpcDogXCJhY3F1aXJlZFwifSlcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgICAgIGVmZmVjdHM6IFtcImhvc3RcIl0sXG4gICAgICAgIGV2YWx1YXRpb25PcmRlcjogXCJsZWZ0LXRvLXJpZ2h0XCIsXG4gICAgICAgIGZhaWx1cmVzOiBbXCJQcm9iZVJlYWRGYWlsdXJlXCIsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiXSxcbiAgICAgICAgbmFtZTogXCJwcm9iZVJlYWRcIixcbiAgICAgICAgcGFyYW1ldGVyczogW3tuYW1lOiBcInJlc291cmNlXCIsIHR5cGU6IFwiUHJvYmVSZXNvdXJjZVwifSwge25hbWU6IFwiZmFpbFwiLCB0eXBlOiBcImJvb2xlYW5cIn1dLFxuICAgICAgICByZXNvdXJjZUZsb3c6IHtraW5kOiBcImJvcnJvd1wiLCBwYXJhbWV0ZXJJbmRleDogMCwgdGVybWluYWxGYWlsdXJlOiBcIlByb2JlUmVzb3VyY2VDbG9zZWRcIn0sXG4gICAgICAgIHJldHVyblR5cGU6IFwib3B0aW9uYWw6c3RyaW5nXCIsXG4gICAgICAgIHNlbWFudGljczogY2Fub25pY2FsU2VtYW50aWNzKHtcbiAgICAgICAgICBjbG9zZTogXCJ1c2UtYWZ0ZXItY2xvc2UtZmFpbHNcIixcbiAgICAgICAgICBlb2Y6IFwiYWJzZW50LXZhbHVlXCIsXG4gICAgICAgICAgZW5jb2Rpbmc6IFwidXRmLThcIixcbiAgICAgICAgICBuZXdsaW5lOiBcInN0cmlwLWxpbmUtdGVybWluYXRvclwiLFxuICAgICAgICAgIG93bmVyc2hpcDogXCJib3Jyb3dlZFwiXG4gICAgICAgIH0pXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgICAgICBlZmZlY3RzOiBbXCJob3N0XCJdLFxuICAgICAgICBldmFsdWF0aW9uT3JkZXI6IFwibGVmdC10by1yaWdodFwiLFxuICAgICAgICBmYWlsdXJlczogW1wiUHJvYmVDbG9zZUZhaWx1cmVcIiwgXCJQcm9iZVJlc291cmNlQ2xvc2VkXCJdLFxuICAgICAgICBuYW1lOiBcInByb2JlQ2xvc2VcIixcbiAgICAgICAgcGFyYW1ldGVyczogW3tuYW1lOiBcInJlc291cmNlXCIsIHR5cGU6IFwiUHJvYmVSZXNvdXJjZVwifSwge25hbWU6IFwiZmFpbFwiLCB0eXBlOiBcImJvb2xlYW5cIn1dLFxuICAgICAgICByZXNvdXJjZUZsb3c6IHtraW5kOiBcImNsb3NlXCIsIHBhcmFtZXRlckluZGV4OiAwLCB0ZXJtaW5hbEZhaWx1cmU6IFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwifSxcbiAgICAgICAgcmV0dXJuVHlwZTogXCJ2b2lkXCIsXG4gICAgICAgIHNlbWFudGljczogY2Fub25pY2FsU2VtYW50aWNzKHtjbG9zZTogXCJyZXBlYXRlZC1jbG9zZS1mYWlsc1wiLCBvd25lcnNoaXA6IFwiY29uc3VtZWRcIn0pXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgICAgICBlZmZlY3RzOiBbXCJob3N0XCJdLFxuICAgICAgICBldmFsdWF0aW9uT3JkZXI6IFwibGVmdC10by1yaWdodFwiLFxuICAgICAgICBmYWlsdXJlczogW10sXG4gICAgICAgIG5hbWU6IFwicHJvYmVUcmFjZVwiLFxuICAgICAgICBwYXJhbWV0ZXJzOiBbXSxcbiAgICAgICAgcmVzb3VyY2VGbG93OiB7a2luZDogXCJub25lXCJ9LFxuICAgICAgICByZXR1cm5UeXBlOiBcInN0cmluZ1wiLFxuICAgICAgICBzZW1hbnRpY3M6IGNhbm9uaWNhbFNlbWFudGljcygpXG4gICAgICB9XG4gICAgXSxcbiAgICByZXNvdXJjZXM6IFt7bmFtZTogXCJQcm9iZVJlc291cmNlXCJ9XSxcbiAgICB2ZXJzaW9uOiBcIjEuMC4wXCJcbiAgfVxufVxuXG4vKipcbiAqIERlY2xhcmVzIHRoZSBjb21wbGV0ZSBidWlsdC1pbiBjYW5vbmljYWwgcmVnaXN0cnkgaW5wdXQuXG4gKiBAcmV0dXJucyB7dW5rbm93bltdfSBVbnZhbGlkYXRlZCBidWlsdC1pbiByZWNvcmRzLlxuICovXG5mdW5jdGlvbiBidWlsdGluQ29udHJhY3RzKCkge1xuICByZXR1cm4gW2J1aWx0aW5Qcm9iZUNvbnRyYWN0KCksIGJ1aWx0aW5Tb2NrZXRDbGllbnRDb250cmFjdCgpLCBidWlsdGluVGV4dFN0cmVhbUNvbnRyYWN0KCksXG4gICAgYnVpbHRpbk91dHB1dENvbnRyYWN0KCksIGJ1aWx0aW5SZXNvdXJjZUNvbnRyYWN0KCldXG59XG5cbi8qKlxuICogRGVjbGFyZXMgdGhlIGJ1aWx0LWluIFNvY2tldENsaWVudCB2MSBjb250cmFjdC5cbiAqIEByZXR1cm5zIHt1bmtub3dufSBVbnZhbGlkYXRlZCBTb2NrZXRDbGllbnQgdjEgcmVjb3JkLlxuICovXG5mdW5jdGlvbiBidWlsdGluU29ja2V0Q2xpZW50Q29udHJhY3QoKSB7XG4gIGNvbnN0IGJ5dGVTdHJlYW0gPSB7bW9kdWxlOiBcInNlbWFudGlmb2xkLnJlc291cmNlXCIsIG5hbWU6IFwiQnl0ZVN0cmVhbVwifVxuXG4gIHJldHVybiB7XG4gICAgZGVwZW5kZW5jaWVzOiBbe21vZHVsZTogXCJzZW1hbnRpZm9sZC5yZXNvdXJjZVwiLCByYW5nZTogXCIxXCJ9XSxcbiAgICBmYWlsdXJlczogW3tuYW1lOiBcIkludmFsaWRIb3N0XCJ9LCB7bmFtZTogXCJJbnZhbGlkUG9ydFwifSwge25hbWU6IFwiQ29ubmVjdGlvbkZhaWx1cmVcIn1dLFxuICAgIGlkZW50aXR5OiBcInNlbWFudGlmb2xkLnNvY2tldC1jbGllbnRcIixcbiAgICBvcGVyYXRpb25zOiBbe1xuICAgICAgZGVwZW5kZW5jaWVzOiBbXSwgZWZmZWN0czogW1wiaG9zdFwiXSwgZXZhbHVhdGlvbk9yZGVyOiBcImxlZnQtdG8tcmlnaHRcIixcbiAgICAgIGZhaWx1cmVzOiBbXCJJbnZhbGlkSG9zdFwiLCBcIkludmFsaWRQb3J0XCIsIFwiQ29ubmVjdGlvbkZhaWx1cmVcIl0sIG5hbWU6IFwidjFfY29ubmVjdFwiLFxuICAgICAgcGFyYW1ldGVyczogW3tuYW1lOiBcImhvc3RcIiwgdHlwZTogXCJzdHJpbmdcIn0sIHtuYW1lOiBcInBvcnRcIiwgdHlwZTogXCJpbnRlZ2VyXCJ9XSxcbiAgICAgIHJlc291cmNlRmxvdzoge2tpbmQ6IFwiYWNxdWlyZVwiLCByZXNvdXJjZTogYnl0ZVN0cmVhbX0sIHJldHVyblR5cGU6IGJ5dGVTdHJlYW0sXG4gICAgICBzZW1hbnRpY3M6IGNhbm9uaWNhbFNlbWFudGljcyh7b3duZXJzaGlwOiBcImFjcXVpcmVkXCJ9KVxuICAgIH1dLFxuICAgIHJlc291cmNlczogW10sXG4gICAgdmVyc2lvbjogXCIxLjAuMFwiXG4gIH1cbn1cblxuLyoqXG4gKiBEZWNsYXJlcyB0aGUgYnVpbHQtaW4gVGV4dFN0cmVhbSB2MSBjb250cmFjdC5cbiAqIEByZXR1cm5zIHt1bmtub3dufSBVbnZhbGlkYXRlZCBUZXh0U3RyZWFtIHYxIHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gYnVpbHRpblRleHRTdHJlYW1Db250cmFjdCgpIHtcbiAgY29uc3QgYnl0ZVN0cmVhbSA9IHttb2R1bGU6IFwic2VtYW50aWZvbGQucmVzb3VyY2VcIiwgbmFtZTogXCJCeXRlU3RyZWFtXCJ9XG4gIGNvbnN0IHJlc291cmNlQ2xvc2VkID0ge21vZHVsZTogXCJzZW1hbnRpZm9sZC5yZXNvdXJjZVwiLCBuYW1lOiBcIlJlc291cmNlQ2xvc2VkXCJ9XG5cbiAgcmV0dXJuIHtcbiAgICBkZXBlbmRlbmNpZXM6IFt7bW9kdWxlOiBcInNlbWFudGlmb2xkLnJlc291cmNlXCIsIHJhbmdlOiBcIjFcIn1dLFxuICAgIGZhaWx1cmVzOiBbe25hbWU6IFwiUmVhZEZhaWx1cmVcIn0sIHtuYW1lOiBcIkRlY29kZUZhaWx1cmVcIn1dLFxuICAgIGlkZW50aXR5OiBcInNlbWFudGlmb2xkLnRleHQtc3RyZWFtXCIsXG4gICAgb3BlcmF0aW9uczogW3tcbiAgICAgIGRlcGVuZGVuY2llczogW10sIGVmZmVjdHM6IFtcImhvc3RcIl0sIGV2YWx1YXRpb25PcmRlcjogXCJsZWZ0LXRvLXJpZ2h0XCIsXG4gICAgICBmYWlsdXJlczogW1wiUmVhZEZhaWx1cmVcIiwgXCJEZWNvZGVGYWlsdXJlXCIsIHJlc291cmNlQ2xvc2VkXSwgbmFtZTogXCJ2MV9yZWFkX2xpbmVcIixcbiAgICAgIHBhcmFtZXRlcnM6IFt7bmFtZTogXCJyZXNvdXJjZVwiLCB0eXBlOiBieXRlU3RyZWFtfV0sXG4gICAgICByZXNvdXJjZUZsb3c6IHtraW5kOiBcImJvcnJvd1wiLCBwYXJhbWV0ZXJJbmRleDogMCwgdGVybWluYWxGYWlsdXJlOiByZXNvdXJjZUNsb3NlZH0sXG4gICAgICByZXR1cm5UeXBlOiBcIm9wdGlvbmFsOnN0cmluZ1wiLFxuICAgICAgc2VtYW50aWNzOiBjYW5vbmljYWxTZW1hbnRpY3Moe2Nsb3NlOiBcInVzZS1hZnRlci1jbG9zZS1mYWlsc1wiLCBlb2Y6IFwiYWJzZW50LXZhbHVlXCIsIGVuY29kaW5nOiBcInV0Zi04XCIsXG4gICAgICAgIG5ld2xpbmU6IFwicmV0YWluLWxpbmUtdGVybWluYXRvclwiLCBvd25lcnNoaXA6IFwiYm9ycm93ZWRcIn0pXG4gICAgfV0sXG4gICAgcmVzb3VyY2VzOiBbXSxcbiAgICB2ZXJzaW9uOiBcIjEuMC4wXCJcbiAgfVxufVxuXG4vKipcbiAqIERlY2xhcmVzIHRoZSBidWlsdC1pbiBPdXRwdXQgdjEgY29udHJhY3QuXG4gKiBAcmV0dXJucyB7dW5rbm93bn0gVW52YWxpZGF0ZWQgT3V0cHV0IHYxIHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gYnVpbHRpbk91dHB1dENvbnRyYWN0KCkge1xuICByZXR1cm4ge1xuICAgIGRlcGVuZGVuY2llczogW10sIGZhaWx1cmVzOiBbe25hbWU6IFwiV3JpdGVGYWlsdXJlXCJ9XSwgaWRlbnRpdHk6IFwic2VtYW50aWZvbGQub3V0cHV0XCIsXG4gICAgb3BlcmF0aW9uczogW3tcbiAgICAgIGRlcGVuZGVuY2llczogW10sIGVmZmVjdHM6IFtcImhvc3RcIl0sIGV2YWx1YXRpb25PcmRlcjogXCJsZWZ0LXRvLXJpZ2h0XCIsIGZhaWx1cmVzOiBbXCJXcml0ZUZhaWx1cmVcIl0sXG4gICAgICBuYW1lOiBcInYxX3dyaXRlX2xpbmVcIiwgcGFyYW1ldGVyczogW3tuYW1lOiBcInRleHRcIiwgdHlwZTogXCJzdHJpbmdcIn1dLCByZXNvdXJjZUZsb3c6IHtraW5kOiBcIm5vbmVcIn0sXG4gICAgICByZXR1cm5UeXBlOiBcInZvaWRcIiwgc2VtYW50aWNzOiBjYW5vbmljYWxTZW1hbnRpY3Moe2VuY29kaW5nOiBcInV0Zi04XCIsIG5ld2xpbmU6IFwiYXBwZW5kLWxmLWlmLW1pc3NpbmdcIn0pXG4gICAgfV0sXG4gICAgcmVzb3VyY2VzOiBbXSwgdmVyc2lvbjogXCIxLjAuMFwiXG4gIH1cbn1cblxuLyoqXG4gKiBEZWNsYXJlcyB0aGUgYnVpbHQtaW4gUmVzb3VyY2UgdjEgY29udHJhY3QuXG4gKiBAcmV0dXJucyB7dW5rbm93bn0gVW52YWxpZGF0ZWQgUmVzb3VyY2UgdjEgcmVjb3JkLlxuICovXG5mdW5jdGlvbiBidWlsdGluUmVzb3VyY2VDb250cmFjdCgpIHtcbiAgcmV0dXJuIHtcbiAgICBkZXBlbmRlbmNpZXM6IFtdLCBmYWlsdXJlczogW3tuYW1lOiBcIkNsb3NlRmFpbHVyZVwifSwge25hbWU6IFwiUmVzb3VyY2VDbG9zZWRcIn1dLCBpZGVudGl0eTogXCJzZW1hbnRpZm9sZC5yZXNvdXJjZVwiLFxuICAgIG9wZXJhdGlvbnM6IFt7XG4gICAgICBkZXBlbmRlbmNpZXM6IFtdLCBlZmZlY3RzOiBbXCJob3N0XCJdLCBldmFsdWF0aW9uT3JkZXI6IFwibGVmdC10by1yaWdodFwiLFxuICAgICAgZmFpbHVyZXM6IFtcIkNsb3NlRmFpbHVyZVwiLCBcIlJlc291cmNlQ2xvc2VkXCJdLCBuYW1lOiBcInYxX2Nsb3NlXCIsXG4gICAgICBwYXJhbWV0ZXJzOiBbe25hbWU6IFwicmVzb3VyY2VcIiwgdHlwZTogXCJCeXRlU3RyZWFtXCJ9XSxcbiAgICAgIHJlc291cmNlRmxvdzoge2tpbmQ6IFwiY2xvc2VcIiwgcGFyYW1ldGVySW5kZXg6IDAsIHRlcm1pbmFsRmFpbHVyZTogXCJSZXNvdXJjZUNsb3NlZFwifSwgcmV0dXJuVHlwZTogXCJ2b2lkXCIsXG4gICAgICBzZW1hbnRpY3M6IGNhbm9uaWNhbFNlbWFudGljcyh7Y2xvc2U6IFwicmVwZWF0ZWQtY2xvc2UtZmFpbHNcIiwgb3duZXJzaGlwOiBcImNvbnN1bWVkXCJ9KVxuICAgIH1dLFxuICAgIHJlc291cmNlczogW3tuYW1lOiBcIkJ5dGVTdHJlYW1cIn1dLCB2ZXJzaW9uOiBcIjEuMC4wXCJcbiAgfVxufVxuXG4vKipcbiAqIEJ1aWxkcyBvbmUgY2xvc2VkIHNlbWFudGljcyBkZWNsYXJhdGlvbiB3aXRoIGNhbm9uaWNhbCBkZWZhdWx0cy5cbiAqIEBwYXJhbSB7UGFydGlhbDxSZWNvcmQ8a2V5b2YgdHlwZW9mIHNlbWFudGljc1ZhbHVlcywgc3RyaW5nPj59IFtvdmVycmlkZXNdIC0gTm9uLWRlZmF1bHQgY2xvc2VkIHZhbHVlcy5cbiAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSBDbG9zZWQgc2VtYW50aWNzIGZpZWxkcy5cbiAqL1xuZnVuY3Rpb24gY2Fub25pY2FsU2VtYW50aWNzKG92ZXJyaWRlcyA9IHt9KSB7XG4gIHJldHVybiB7XG4gICAgYmxvY2tpbmc6IFwic3luY2hyb25vdXNcIixcbiAgICBjbG9zZTogXCJub3QtYXBwbGljYWJsZVwiLFxuICAgIGVvZjogXCJub3QtYXBwbGljYWJsZVwiLFxuICAgIGVuY29kaW5nOiBcIm5vdC1hcHBsaWNhYmxlXCIsXG4gICAgbmV3bGluZTogXCJub3QtYXBwbGljYWJsZVwiLFxuICAgIG93bmVyc2hpcDogXCJub3QtYXBwbGljYWJsZVwiLFxuICAgIHRpbWVvdXQ6IFwibm9uZVwiLFxuICAgIC4uLm92ZXJyaWRlc1xuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBjYW5vbmljYWwgY29udHJhY3QgcmVjb3JkIGFuZCByZXR1cm5zIGEgZGV0YWNoZWQgY2xvbmUuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSByZWNvcmQuXG4gKiBAcmV0dXJucyB7U3RkbGliQ29udHJhY3RNb2R1bGV9IERldGFjaGVkIHJlY29yZC5cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVDb250cmFjdFJlY29yZChjYW5kaWRhdGUpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkpIGludmFsaWRDb250cmFjdChcIkV2ZXJ5IGNhbm9uaWNhbCBjb250cmFjdCByZWNvcmQgbXVzdCBiZSBhIHBsYWluIG9iamVjdC5cIilcbiAgcmVxdWlyZUtleXMoY2FuZGlkYXRlLCBbXCJkZXBlbmRlbmNpZXNcIiwgXCJmYWlsdXJlc1wiLCBcImlkZW50aXR5XCIsIFwib3BlcmF0aW9uc1wiLCBcInJlc291cmNlc1wiLCBcInZlcnNpb25cIl0sIFwiY29udHJhY3QgcmVjb3JkXCIpXG4gIGNvbnN0IGlkZW50aXR5ID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChjYW5kaWRhdGUuaWRlbnRpdHkpXG5cbiAgaWYgKHR5cGVvZiBpZGVudGl0eSAhPSBcInN0cmluZ1wiIHx8ICFpZGVudGl0eVBhdHRlcm4udGVzdChpZGVudGl0eSkpIGludmFsaWRDb250cmFjdChcIkNhbm9uaWNhbCBjb250cmFjdCBpZGVudGl0eSBpcyBpbnZhbGlkLlwiKVxuICBjb25zdCB2ZXJzaW9uID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChjYW5kaWRhdGUudmVyc2lvbilcblxuICBpZiAocGFyc2VTdGRsaWJWZXJzaW9uKHZlcnNpb24pID09PSBudWxsKSBpbnZhbGlkQ29udHJhY3QoYENhbm9uaWNhbCBjb250cmFjdCB2ZXJzaW9uICcke1N0cmluZyh2ZXJzaW9uKX0nIGlzIGludmFsaWQuYClcbiAgY29uc3QgcmVzb3VyY2VzID0gdmFsaWRhdGVOYW1lZExpc3QoY2FuZGlkYXRlLnJlc291cmNlcywgXCJyZXNvdXJjZVwiKVxuICBjb25zdCBmYWlsdXJlcyA9IHZhbGlkYXRlTmFtZWRMaXN0KGNhbmRpZGF0ZS5mYWlsdXJlcywgXCJmYWlsdXJlXCIpXG4gIGNvbnN0IHJlc291cmNlTmFtZXMgPSBuZXcgU2V0KHJlc291cmNlcy5tYXAoKHtuYW1lfSkgPT4gbmFtZSkpXG4gIGNvbnN0IGZhaWx1cmVOYW1lcyA9IG5ldyBTZXQoZmFpbHVyZXMubWFwKCh7bmFtZX0pID0+IG5hbWUpKVxuICBjb25zdCBvcGVyYXRpb25OYW1lcyA9IG5ldyBTZXQoKVxuICBjb25zdCBkZXBlbmRlbmNpZXMgPSB2YWxpZGF0ZU1vZHVsZURlcGVuZGVuY2llcyhjYW5kaWRhdGUuZGVwZW5kZW5jaWVzLCBpZGVudGl0eSlcblxuICBpZiAoIWlzRGVuc2VBcnJheShjYW5kaWRhdGUub3BlcmF0aW9ucykpIGludmFsaWRDb250cmFjdChcIkNhbm9uaWNhbCBjb250cmFjdCBvcGVyYXRpb25zIG11c3QgYmUgYSBkZW5zZSBhcnJheS5cIilcbiAgY29uc3Qgb3BlcmF0aW9ucyA9IC8qKiBAdHlwZSB7dW5rbm93bltdfSAqLyAoY2FuZGlkYXRlLm9wZXJhdGlvbnMpLm1hcCgob3BlcmF0aW9uKSA9PlxuICAgIHZhbGlkYXRlQ29udHJhY3RPcGVyYXRpb24ob3BlcmF0aW9uLCByZXNvdXJjZU5hbWVzLCBmYWlsdXJlTmFtZXMsIG9wZXJhdGlvbk5hbWVzKSlcblxuICByZXR1cm4gZGVlcEZyZWV6ZSh7XG4gICAgZGVwZW5kZW5jaWVzLFxuICAgIGZhaWx1cmVzLFxuICAgIGlkZW50aXR5LFxuICAgIG9wZXJhdGlvbnMsXG4gICAgcmVzb3VyY2VzLFxuICAgIHZlcnNpb246IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAodmVyc2lvbilcbiAgfSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIGNhbm9uaWNhbCBjb250cmFjdCBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSByZXNvdXJjZU5hbWVzIC0gRGVjbGFyZWQgcmVzb3VyY2UgbmFtZXMuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBmYWlsdXJlTmFtZXMgLSBEZWNsYXJlZCBmYWlsdXJlIG5hbWVzLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gb3BlcmF0aW9uTmFtZXMgLSBBbHJlYWR5LWRlY2xhcmVkIG9wZXJhdGlvbiBuYW1lcy5cbiAqIEByZXR1cm5zIHtTdGRsaWJDb250cmFjdE9wZXJhdGlvbn0gRGV0YWNoZWQgb3BlcmF0aW9uLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUNvbnRyYWN0T3BlcmF0aW9uKGNhbmRpZGF0ZSwgcmVzb3VyY2VOYW1lcywgZmFpbHVyZU5hbWVzLCBvcGVyYXRpb25OYW1lcykge1xuICBpZiAoIWlzUGxhaW5PYmplY3QoY2FuZGlkYXRlKSkgaW52YWxpZENvbnRyYWN0KFwiRXZlcnkgY2Fub25pY2FsIGNvbnRyYWN0IG9wZXJhdGlvbiBtdXN0IGJlIGEgcGxhaW4gb2JqZWN0LlwiKVxuICByZXF1aXJlS2V5cyhjYW5kaWRhdGUsIFtcImRlcGVuZGVuY2llc1wiLCBcImVmZmVjdHNcIiwgXCJldmFsdWF0aW9uT3JkZXJcIiwgXCJmYWlsdXJlc1wiLCBcIm5hbWVcIiwgXCJwYXJhbWV0ZXJzXCIsIFwicmVzb3VyY2VGbG93XCIsIFwicmV0dXJuVHlwZVwiLCBcInNlbWFudGljc1wiXSwgXCJjb250cmFjdCBvcGVyYXRpb25cIilcbiAgY29uc3QgbmFtZSA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoY2FuZGlkYXRlLm5hbWUpXG5cbiAgaWYgKHR5cGVvZiBuYW1lICE9IFwic3RyaW5nXCIgfHwgIWRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChuYW1lKSB8fCBvcGVyYXRpb25OYW1lcy5oYXMobmFtZSkpIHtcbiAgICBpbnZhbGlkQ29udHJhY3QoXCJDYW5vbmljYWwgY29udHJhY3Qgb3BlcmF0aW9uIG5hbWUgaXMgaW52YWxpZCBvciBkdXBsaWNhdGUuXCIpXG4gIH1cbiAgb3BlcmF0aW9uTmFtZXMuYWRkKG5hbWUpXG4gIGlmICghaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5lZmZlY3RzKSB8fCBjYW5kaWRhdGUuZWZmZWN0cy5sZW5ndGggIT0gMSB8fCBjYW5kaWRhdGUuZWZmZWN0c1swXSAhPSBcImhvc3RcIikge1xuICAgIGludmFsaWRDb250cmFjdChgT3BlcmF0aW9uICcke25hbWV9JyByZXF1aXJlcyB0aGUgc2luZ2xlIGhvc3QgZWZmZWN0IGRlY2xhcmF0aW9uLmApXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5ldmFsdWF0aW9uT3JkZXIgIT0gXCJsZWZ0LXRvLXJpZ2h0XCIpIGludmFsaWRDb250cmFjdChgT3BlcmF0aW9uICcke25hbWV9JyByZXF1aXJlcyBsZWZ0LXRvLXJpZ2h0IGV2YWx1YXRpb24uYClcbiAgaWYgKCFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlLmZhaWx1cmVzKSkge1xuICAgIGludmFsaWRDb250cmFjdChgT3BlcmF0aW9uICcke25hbWV9JyBkZWNsYXJlcyB1bmtub3duIG9yIGR1cGxpY2F0ZSBmYWlsdXJlcy5gKVxuICB9XG4gIGNvbnN0IGZhaWx1cmVzID0gY2FuZGlkYXRlLmZhaWx1cmVzLm1hcCgoZmFpbHVyZSkgPT4gbm9ybWFsaXplRGVjbGFyYXRpb25SZWZlcmVuY2UoZmFpbHVyZSwgZmFpbHVyZU5hbWVzLCBgT3BlcmF0aW9uICcke25hbWV9JyBmYWlsdXJlYCkpXG4gIGlmIChuZXcgU2V0KGZhaWx1cmVzLm1hcChyZWZlcmVuY2VLZXkpKS5zaXplICE9IGZhaWx1cmVzLmxlbmd0aCkgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7bmFtZX0nIHJlcGVhdHMgYSBkZWNsYXJlZCBmYWlsdXJlLmApXG4gIGNvbnN0IHBhcmFtZXRlck5hbWVzID0gbmV3IFNldCgpXG4gIC8qKiBAdHlwZSB7e25hbWU6IHN0cmluZywgdHlwZTogc3RyaW5nIHwgQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2V9W119ICovXG4gIGNvbnN0IHBhcmFtZXRlcnMgPSBbXVxuXG4gIGlmICghaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5wYXJhbWV0ZXJzKSkgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7bmFtZX0nIHBhcmFtZXRlcnMgbXVzdCBiZSBhIGRlbnNlIGFycmF5LmApXG4gIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIC8qKiBAdHlwZSB7dW5rbm93bltdfSAqLyAoY2FuZGlkYXRlLnBhcmFtZXRlcnMpKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHBhcmFtZXRlcikpIGludmFsaWRDb250cmFjdChgT3BlcmF0aW9uICcke25hbWV9JyBwYXJhbWV0ZXJzIG11c3QgYmUgcGxhaW4gb2JqZWN0cy5gKVxuICAgIHJlcXVpcmVLZXlzKHBhcmFtZXRlciwgW1wibmFtZVwiLCBcInR5cGVcIl0sIGBvcGVyYXRpb24gJyR7bmFtZX0nIHBhcmFtZXRlcmApXG4gICAgY29uc3QgcGFyYW1ldGVyTmFtZSA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocGFyYW1ldGVyLm5hbWUpXG5cbiAgICBpZiAodHlwZW9mIHBhcmFtZXRlck5hbWUgIT0gXCJzdHJpbmdcIiB8fCAhZGVjbGFyYXRpb25OYW1lUGF0dGVybi50ZXN0KHBhcmFtZXRlck5hbWUpIHx8IHBhcmFtZXRlck5hbWVzLmhhcyhwYXJhbWV0ZXJOYW1lKSkge1xuICAgICAgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7bmFtZX0nIHBhcmFtZXRlciBuYW1lIGlzIGludmFsaWQgb3IgZHVwbGljYXRlLmApXG4gICAgfVxuICAgIHBhcmFtZXRlck5hbWVzLmFkZChwYXJhbWV0ZXJOYW1lKVxuICAgIGNvbnN0IHBhcmFtZXRlclR5cGUgPSBub3JtYWxpemVDYW5vbmljYWxWYWx1ZVR5cGUocGFyYW1ldGVyLnR5cGUsIHJlc291cmNlTmFtZXMsIGBvcGVyYXRpb24gJyR7bmFtZX0nIHBhcmFtZXRlciAnJHtwYXJhbWV0ZXJOYW1lfSdgKVxuXG4gICAgaWYgKHBhcmFtZXRlclR5cGUgPT09IG51bGwpIHtcbiAgICAgIGludmFsaWRDb250cmFjdChgT3BlcmF0aW9uICcke25hbWV9JyBwYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nIHR5cGUgaXMgb3V0c2lkZSB0aGUgY2xvc2VkIGNhbm9uaWNhbCB2YWx1ZSBzZXQuYClcbiAgICB9XG4gICAgcGFyYW1ldGVycy5wdXNoKHtuYW1lOiBwYXJhbWV0ZXJOYW1lLCB0eXBlOiBwYXJhbWV0ZXJUeXBlfSlcbiAgfVxuICBjb25zdCByZXR1cm5UeXBlID0gY2FuZGlkYXRlLnJldHVyblR5cGUgPT0gXCJ2b2lkXCIgPyBcInZvaWRcIiA6IG5vcm1hbGl6ZUNhbm9uaWNhbFZhbHVlVHlwZShjYW5kaWRhdGUucmV0dXJuVHlwZSwgcmVzb3VyY2VOYW1lcywgYG9wZXJhdGlvbiAnJHtuYW1lfScgcmV0dXJuIHR5cGVgKVxuXG4gIGlmIChyZXR1cm5UeXBlID09PSBudWxsKSB7XG4gICAgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7bmFtZX0nIHJldHVybiB0eXBlIGlzIG91dHNpZGUgdGhlIGNsb3NlZCBjYW5vbmljYWwgdmFsdWUgc2V0LmApXG4gIH1cbiAgY29uc3QgcmVzb3VyY2VGbG93ID0gdmFsaWRhdGVDb250cmFjdFJlc291cmNlRmxvdyhjYW5kaWRhdGUucmVzb3VyY2VGbG93LCBwYXJhbWV0ZXJzLCBmYWlsdXJlcywgbmFtZSlcbiAgY29uc3QgZGVwZW5kZW5jaWVzID0gdmFsaWRhdGVPcGVyYXRpb25EZXBlbmRlbmNpZXMoY2FuZGlkYXRlLmRlcGVuZGVuY2llcylcbiAgY29uc3Qgc2VtYW50aWNzID0gdmFsaWRhdGVDb250cmFjdFNlbWFudGljcyhjYW5kaWRhdGUuc2VtYW50aWNzLCBuYW1lKVxuXG4gIHJldHVybiBkZWVwRnJlZXplKHtcbiAgICBkZXBlbmRlbmNpZXMsXG4gICAgZWZmZWN0czogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFtcImhvc3RcIl0pLFxuICAgIGV2YWx1YXRpb25PcmRlcjogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwibGVmdC10by1yaWdodFwiKSxcbiAgICBmYWlsdXJlcyxcbiAgICBuYW1lLFxuICAgIHBhcmFtZXRlcnMsXG4gICAgcmVzb3VyY2VGbG93LFxuICAgIHJldHVyblR5cGUsXG4gICAgc2VtYW50aWNzXG4gIH0pXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBjbG9zZWQgY2Fub25pY2FsIHZhbHVlIHR5cGUgc3BlbGxpbmcuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSB0eXBlLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gcmVzb3VyY2VOYW1lcyAtIERlY2xhcmVkIHJlc291cmNlIG5hbWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IF9zdWJqZWN0IC0gRGlhZ25vc3RpYyBzdWJqZWN0IHJlc2VydmVkIGZvciBjYWxsZXIgY29udGV4dC5cbiAqIEByZXR1cm5zIHtzdHJpbmcgfCBDYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZSB8IG51bGx9IERldGFjaGVkIHR5cGUgb3IgbnVsbC5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplQ2Fub25pY2FsVmFsdWVUeXBlKGNhbmRpZGF0ZSwgcmVzb3VyY2VOYW1lcywgX3N1YmplY3QpIHtcbiAgaWYgKHR5cGVvZiBjYW5kaWRhdGUgPT0gXCJzdHJpbmdcIikge1xuICAgIGlmIChzY2FsYXJOYW1lcy5oYXMoY2FuZGlkYXRlKSB8fCByZXNvdXJjZU5hbWVzLmhhcyhjYW5kaWRhdGUpKSByZXR1cm4gY2FuZGlkYXRlXG4gICAgY29uc3Qgb3B0aW9uYWwgPSAvXm9wdGlvbmFsOihbYS16XSspJC91LmV4ZWMoY2FuZGlkYXRlKVxuXG4gICAgcmV0dXJuIG9wdGlvbmFsICYmIHNjYWxhck5hbWVzLmhhcyhvcHRpb25hbFsxXSkgPyBjYW5kaWRhdGUgOiBudWxsXG4gIH1cbiAgaWYgKGlzUGxhaW5PYmplY3QoY2FuZGlkYXRlKSAmJiBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLnNvcnQoKS5qb2luKFwiLFwiKSA9PSBcIm1vZHVsZSxuYW1lXCIgJiZcbiAgICB0eXBlb2YgY2FuZGlkYXRlLm1vZHVsZSA9PSBcInN0cmluZ1wiICYmIGlkZW50aXR5UGF0dGVybi50ZXN0KGNhbmRpZGF0ZS5tb2R1bGUpICYmIHR5cGVvZiBjYW5kaWRhdGUubmFtZSA9PSBcInN0cmluZ1wiICYmXG4gICAgZGVjbGFyYXRpb25OYW1lUGF0dGVybi50ZXN0KGNhbmRpZGF0ZS5uYW1lKSkgcmV0dXJuIHttb2R1bGU6IGNhbmRpZGF0ZS5tb2R1bGUsIG5hbWU6IGNhbmRpZGF0ZS5uYW1lfVxuICByZXR1cm4gbnVsbFxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgY2xvc2VkIHJlc291cmNlIHRyYW5zaXRpb24gYWdhaW5zdCBpdHMgcGFyYW1ldGVycyBhbmQgZmFpbHVyZXMuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSB0cmFuc2l0aW9uLlxuICogQHBhcmFtIHt7bmFtZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcgfCBDYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX1bXX0gcGFyYW1ldGVycyAtIFZhbGlkYXRlZCBwYXJhbWV0ZXJzLlxuICogQHBhcmFtIHsoc3RyaW5nIHwgQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2UpW119IGZhaWx1cmVzIC0gVmFsaWRhdGVkIGZhaWx1cmUgbmFtZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIC0gT3BlcmF0aW9uIG5hbWUuXG4gKiBAcmV0dXJucyB7b2JqZWN0fSBEZXRhY2hlZCB0cmFuc2l0aW9uLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUNvbnRyYWN0UmVzb3VyY2VGbG93KGNhbmRpZGF0ZSwgcGFyYW1ldGVycywgZmFpbHVyZXMsIG9wZXJhdGlvbikge1xuICBpZiAoIWlzUGxhaW5PYmplY3QoY2FuZGlkYXRlKSkgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7b3BlcmF0aW9ufScgcmVxdWlyZXMgYSByZXNvdXJjZSBmbG93IGRlY2xhcmF0aW9uLmApXG4gIGNvbnN0IG93bmVkUGFyYW1ldGVycyA9IHBhcmFtZXRlcnMuZmxhdE1hcCgocGFyYW1ldGVyLCBpbmRleCkgPT4gaXNPd25lZENhbm9uaWNhbFR5cGUocGFyYW1ldGVyLnR5cGUpID8gW2luZGV4XSA6IFtdKVxuXG4gIGlmIChPYmplY3Qua2V5cyhjYW5kaWRhdGUpLnNvcnQoKS5qb2luKFwiLFwiKSA9PSBcImtpbmRcIiAmJiBjYW5kaWRhdGUua2luZCA9PSBcIm5vbmVcIikge1xuICAgIGlmIChvd25lZFBhcmFtZXRlcnMubGVuZ3RoID4gMCkgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7b3BlcmF0aW9ufScgb3ducyBhIHBhcmFtZXRlciB3aXRob3V0IGEgdHJhbnNpdGlvbi5gKVxuICAgIHJldHVybiBkZWVwRnJlZXplKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJub25lXCIpfSlcbiAgfVxuICBpZiAoT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgPT0gXCJraW5kLHJlc291cmNlXCIgJiYgY2FuZGlkYXRlLmtpbmQgPT0gXCJhY3F1aXJlXCIpIHtcbiAgICBjb25zdCByZXNvdXJjZSA9IHR5cGVvZiBjYW5kaWRhdGUucmVzb3VyY2UgPT0gXCJzdHJpbmdcIiAmJiBkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3QoY2FuZGlkYXRlLnJlc291cmNlKVxuICAgICAgPyBjYW5kaWRhdGUucmVzb3VyY2VcbiAgICAgIDogbm9ybWFsaXplQ2Fub25pY2FsVmFsdWVUeXBlKGNhbmRpZGF0ZS5yZXNvdXJjZSwgbmV3IFNldCgpLCBgb3BlcmF0aW9uICcke29wZXJhdGlvbn0nIGFjcXVpc2l0aW9uYClcbiAgICBpZiAocmVzb3VyY2UgPT09IG51bGwgfHwgb3duZWRQYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgIGludmFsaWRDb250cmFjdChgT3BlcmF0aW9uICcke29wZXJhdGlvbn0nIGFjcXVpc2l0aW9uIGZsb3cgaXMgaW5jb21wbGV0ZS5gKVxuICAgIH1cbiAgICByZXR1cm4gZGVlcEZyZWV6ZSh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiYWNxdWlyZVwiKSwgcmVzb3VyY2V9KVxuICB9XG4gIGlmIChbXCJib3Jyb3dcIiwgXCJjbG9zZVwiXS5pbmNsdWRlcyhTdHJpbmcoY2FuZGlkYXRlLmtpbmQpKSAmJlxuICAgIE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuc29ydCgpLmpvaW4oXCIsXCIpID09IFwia2luZCxwYXJhbWV0ZXJJbmRleCx0ZXJtaW5hbEZhaWx1cmVcIikge1xuICAgIGNvbnN0IHBhcmFtZXRlckluZGV4ID0gLyoqIEB0eXBlIHtudW1iZXJ9ICovIChjYW5kaWRhdGUucGFyYW1ldGVySW5kZXgpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHBhcmFtZXRlckluZGV4KSB8fCBwYXJhbWV0ZXJJbmRleCA8IDAgfHwgcGFyYW1ldGVySW5kZXggPj0gcGFyYW1ldGVycy5sZW5ndGggfHxcbiAgICAgIG93bmVkUGFyYW1ldGVycy5sZW5ndGggIT0gMSB8fCBvd25lZFBhcmFtZXRlcnNbMF0gIT0gcGFyYW1ldGVySW5kZXggfHxcbiAgICAgICFmYWlsdXJlcy5zb21lKChmYWlsdXJlKSA9PiByZWZlcmVuY2VLZXkoZmFpbHVyZSkgPT0gcmVmZXJlbmNlS2V5KGNhbmRpZGF0ZS50ZXJtaW5hbEZhaWx1cmUpKSkge1xuICAgICAgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7b3BlcmF0aW9ufScgJHtTdHJpbmcoY2FuZGlkYXRlLmtpbmQpfSBmbG93IGlzIGluY29tcGxldGUuYClcbiAgICB9XG4gICAgcmV0dXJuIGRlZXBGcmVlemUoe2tpbmQ6IC8qKiBAdHlwZSB7XCJib3Jyb3dcIiB8IFwiY2xvc2VcIn0gKi8gKGNhbmRpZGF0ZS5raW5kKSwgcGFyYW1ldGVySW5kZXgsXG4gICAgICB0ZXJtaW5hbEZhaWx1cmU6IG5vcm1hbGl6ZUZhaWx1cmVGbG93UmVmZXJlbmNlKGNhbmRpZGF0ZS50ZXJtaW5hbEZhaWx1cmUpfSlcbiAgfVxuICByZXR1cm4gaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7b3BlcmF0aW9ufScgZGVjbGFyZXMgYW4gdW5rbm93biByZXNvdXJjZSBmbG93LmApXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBjYW5vbmljYWwgb3BlcmF0aW9uIGRlcGVuZGVuY3kgbGlzdC5cbiAqIEBwYXJhbSB7dW5rbm93bn0gY2FuZGlkYXRlIC0gQ2FuZGlkYXRlIGRlcGVuZGVuY2llcy5cbiAqIEByZXR1cm5zIHt7bW9kdWxlOiBzdHJpbmcsIG9wZXJhdGlvbjogc3RyaW5nLCByYW5nZTogVmVyc2lvblJhbmdlfVtdfSBEZXRhY2hlZCBkZXBlbmRlbmNpZXMuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlT3BlcmF0aW9uRGVwZW5kZW5jaWVzKGNhbmRpZGF0ZSkge1xuICBpZiAoIWlzRGVuc2VBcnJheShjYW5kaWRhdGUpKSBpbnZhbGlkQ29udHJhY3QoXCJDYW5vbmljYWwgY29udHJhY3QgZGVwZW5kZW5jaWVzIG11c3QgYmUgYSBkZW5zZSBhcnJheS5cIilcbiAgLyoqIEB0eXBlIHt7bW9kdWxlOiBzdHJpbmcsIG9wZXJhdGlvbjogc3RyaW5nLCByYW5nZTogVmVyc2lvblJhbmdlfVtdfSAqL1xuICBjb25zdCBkZXBlbmRlbmNpZXMgPSBbXVxuXG4gIGZvciAoY29uc3QgZGVwZW5kZW5jeSBvZiBjYW5kaWRhdGUpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QoZGVwZW5kZW5jeSkpIGludmFsaWRDb250cmFjdChcIkV2ZXJ5IGNhbm9uaWNhbCBjb250cmFjdCBkZXBlbmRlbmN5IG11c3QgYmUgYSBwbGFpbiBvYmplY3QuXCIpXG4gICAgcmVxdWlyZUtleXMoZGVwZW5kZW5jeSwgW1wibW9kdWxlXCIsIFwib3BlcmF0aW9uXCIsIFwicmFuZ2VcIl0sIFwiY29udHJhY3QgZGVwZW5kZW5jeVwiKVxuICAgIGNvbnN0IG1vZHVsZSA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVwZW5kZW5jeS5tb2R1bGUpXG4gICAgY29uc3Qgb3BlcmF0aW9uID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZXBlbmRlbmN5Lm9wZXJhdGlvbilcbiAgICBjb25zdCByYW5nZSA9IHBhcnNlU3RkbGliVmVyc2lvblJhbmdlKGRlcGVuZGVuY3kucmFuZ2UpXG5cbiAgICBpZiAodHlwZW9mIG1vZHVsZSAhPSBcInN0cmluZ1wiIHx8ICFpZGVudGl0eVBhdHRlcm4udGVzdChtb2R1bGUpIHx8XG4gICAgICB0eXBlb2Ygb3BlcmF0aW9uICE9IFwic3RyaW5nXCIgfHwgIWRlY2xhcmF0aW9uTmFtZVBhdHRlcm4udGVzdChvcGVyYXRpb24pIHx8IHJhbmdlID09PSBudWxsKSB7XG4gICAgICBpbnZhbGlkQ29udHJhY3QoXCJDYW5vbmljYWwgY29udHJhY3QgZGVwZW5kZW5jeSBtb2R1bGUsIG9wZXJhdGlvbiwgb3IgcmFuZ2UgaXMgaW52YWxpZC5cIilcbiAgICB9XG4gICAgZGVwZW5kZW5jaWVzLnB1c2goe21vZHVsZSwgb3BlcmF0aW9uLCByYW5nZX0pXG4gIH1cbiAgcmV0dXJuIGRlcGVuZGVuY2llc1xufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBjYW5vbmljYWwgb3BlcmF0aW9uIGRlcGVuZGVuY2llcyBhZ2FpbnN0IHRoZSBjb21wbGV0ZSByZWdpc3RyeSBpZGVudGl0eSBzZXQuXG4gKiBAcGFyYW0ge1N0ZGxpYkNvbnRyYWN0TW9kdWxlfSByZWNvcmQgLSBWYWxpZGF0ZWQgcmVjb3JkLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBTdGRsaWJDb250cmFjdE1vZHVsZT4+fSBtb2R1bGVzIC0gQWxsIHJlZ2lzdGVyZWQgbW9kdWxlIHZlcnNpb25zLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQ29udHJhY3REZXBlbmRlbmNpZXMocmVjb3JkLCBtb2R1bGVzKSB7XG4gIGNvbnN0IGFsbG93ZWREZXBlbmRlbmNpZXMgPSBuZXcgTWFwKHJlY29yZC5kZXBlbmRlbmNpZXMubWFwKChkZXBlbmRlbmN5KSA9PiBbZGVwZW5kZW5jeS5tb2R1bGUsIGRlcGVuZGVuY3kucmFuZ2VdKSlcblxuICBmb3IgKGNvbnN0IGRlcGVuZGVuY3kgb2YgcmVjb3JkLmRlcGVuZGVuY2llcykge1xuICAgIGNvbnN0IHZlcnNpb25zID0gbW9kdWxlcy5nZXQoZGVwZW5kZW5jeS5tb2R1bGUpXG5cbiAgICBpZiAoIXZlcnNpb25zIHx8ICFbLi4udmVyc2lvbnMua2V5cygpXS5zb21lKCh2ZXJzaW9uKSA9PiBzdGRsaWJWZXJzaW9uU2F0aXNmaWVzKC8qKiBAdHlwZSB7VmVyc2lvblR1cGxlfSAqLyAocGFyc2VTdGRsaWJWZXJzaW9uKHZlcnNpb24pKSwgZGVwZW5kZW5jeS5yYW5nZSkpKSB7XG4gICAgICBpbnZhbGlkQ29udHJhY3QoYENhbm9uaWNhbCBtb2R1bGUgJyR7cmVjb3JkLmlkZW50aXR5fScgZGVwZW5kcyBvbiBtaXNzaW5nIG9yIGluY29tcGF0aWJsZSBtb2R1bGUgJyR7ZGVwZW5kZW5jeS5tb2R1bGV9Jy5gKVxuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiByZWNvcmQub3BlcmF0aW9ucykge1xuICAgIGZvciAoY29uc3QgcmVmZXJlbmNlIG9mIG9wZXJhdGlvbi5wYXJhbWV0ZXJzLm1hcCgoe3R5cGV9KSA9PiB0eXBlKS5jb25jYXQoW29wZXJhdGlvbi5yZXR1cm5UeXBlXSkuZmlsdGVyKGlzRGVjbGFyYXRpb25SZWZlcmVuY2UpKSB7XG4gICAgICB2YWxpZGF0ZUZvcmVpZ25EZWNsYXJhdGlvblJlZmVyZW5jZShyZWNvcmQsIHJlZmVyZW5jZSwgXCJyZXNvdXJjZVwiLCBhbGxvd2VkRGVwZW5kZW5jaWVzLCBtb2R1bGVzKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IHJlZmVyZW5jZSBvZiBvcGVyYXRpb24uZmFpbHVyZXMuZmlsdGVyKGlzRGVjbGFyYXRpb25SZWZlcmVuY2UpKSB7XG4gICAgICB2YWxpZGF0ZUZvcmVpZ25EZWNsYXJhdGlvblJlZmVyZW5jZShyZWNvcmQsIHJlZmVyZW5jZSwgXCJmYWlsdXJlXCIsIGFsbG93ZWREZXBlbmRlbmNpZXMsIG1vZHVsZXMpXG4gICAgfVxuICAgIGZvciAoY29uc3QgZGVwZW5kZW5jeSBvZiBvcGVyYXRpb24uZGVwZW5kZW5jaWVzKSB7XG4gICAgICBpZiAoIW1vZHVsZXMuaGFzKGRlcGVuZGVuY3kubW9kdWxlKSkge1xuICAgICAgICBpbnZhbGlkQ29udHJhY3QoYE9wZXJhdGlvbiAnJHtvcGVyYXRpb24ubmFtZX0nIGRlcGVuZHMgb24gdW5rbm93biBjYW5vbmljYWwgbW9kdWxlICcke2RlcGVuZGVuY3kubW9kdWxlfScuYClcbiAgICAgIH1cbiAgICAgIGlmIChkZXBlbmRlbmN5Lm1vZHVsZSA9PSByZWNvcmQuaWRlbnRpdHkgJiYgZGVwZW5kZW5jeS5vcGVyYXRpb24gPT0gb3BlcmF0aW9uLm5hbWUpIHtcbiAgICAgICAgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7b3BlcmF0aW9uLm5hbWV9JyBkZWNsYXJlcyBhIHNlbGYtY3ljbGUgZGVwZW5kZW5jeS5gKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBkZWNsYXJhdGlvbi1vbmx5IG1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBkZXBlbmRlbmN5IGxpc3QuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHkgLSBPd25pbmcgbW9kdWxlIGlkZW50aXR5LlxuICogQHJldHVybnMge3ttb2R1bGU6IHN0cmluZywgcmFuZ2U6IFZlcnNpb25SYW5nZX1bXX0gRGV0YWNoZWQgZGVwZW5kZW5jaWVzLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZU1vZHVsZURlcGVuZGVuY2llcyhjYW5kaWRhdGUsIGlkZW50aXR5KSB7XG4gIGlmICghaXNEZW5zZUFycmF5KGNhbmRpZGF0ZSkpIGludmFsaWRDb250cmFjdChcIkNhbm9uaWNhbCBtb2R1bGUgZGVwZW5kZW5jaWVzIG11c3QgYmUgYSBkZW5zZSBhcnJheS5cIilcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0KClcblxuICByZXR1cm4gY2FuZGlkYXRlLm1hcCgoZGVwZW5kZW5jeSkgPT4ge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChkZXBlbmRlbmN5KSkgaW52YWxpZENvbnRyYWN0KFwiRXZlcnkgY2Fub25pY2FsIG1vZHVsZSBkZXBlbmRlbmN5IG11c3QgYmUgYSBwbGFpbiBvYmplY3QuXCIpXG4gICAgcmVxdWlyZUtleXMoZGVwZW5kZW5jeSwgW1wibW9kdWxlXCIsIFwicmFuZ2VcIl0sIFwibW9kdWxlIGRlcGVuZGVuY3lcIilcbiAgICBjb25zdCBtb2R1bGUgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlcGVuZGVuY3kubW9kdWxlKVxuICAgIGNvbnN0IHJhbmdlID0gcGFyc2VTdGRsaWJWZXJzaW9uUmFuZ2UoZGVwZW5kZW5jeS5yYW5nZSlcblxuICAgIGlmICh0eXBlb2YgbW9kdWxlICE9IFwic3RyaW5nXCIgfHwgIWlkZW50aXR5UGF0dGVybi50ZXN0KG1vZHVsZSkgfHwgbW9kdWxlID09IGlkZW50aXR5IHx8IG5hbWVzLmhhcyhtb2R1bGUpIHx8IHJhbmdlID09PSBudWxsKSB7XG4gICAgICBpbnZhbGlkQ29udHJhY3QoXCJDYW5vbmljYWwgbW9kdWxlIGRlcGVuZGVuY3kgaXMgaW52YWxpZCwgZHVwbGljYXRlLCBzZWxmLXJlZmVyZW50aWFsLCBvciBtYWxmb3JtZWQuXCIpXG4gICAgfVxuICAgIG5hbWVzLmFkZChtb2R1bGUpXG4gICAgcmV0dXJuIHttb2R1bGUsIHJhbmdlfVxuICB9KVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgZGVwZW5kZW5jeS1xdWFsaWZpZWQgcmVzb3VyY2Ugb3IgZmFpbHVyZSByZWZlcmVuY2UuXG4gKiBAcGFyYW0ge1N0ZGxpYkNvbnRyYWN0TW9kdWxlfSByZWNvcmQgLSBPd25pbmcgbW9kdWxlLlxuICogQHBhcmFtIHtDYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gcmVmZXJlbmNlIC0gUXVhbGlmaWVkIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtcInJlc291cmNlXCIgfCBcImZhaWx1cmVcIn0ga2luZCAtIERlY2xhcmF0aW9uIGtpbmQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFZlcnNpb25SYW5nZT59IGFsbG93ZWREZXBlbmRlbmNpZXMgLSBEaXJlY3QgZGVwZW5kZW5jeSByYW5nZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIFN0ZGxpYkNvbnRyYWN0TW9kdWxlPj59IG1vZHVsZXMgLSBSZWdpc3RyeSBtb2R1bGVzLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRm9yZWlnbkRlY2xhcmF0aW9uUmVmZXJlbmNlKHJlY29yZCwgcmVmZXJlbmNlLCBraW5kLCBhbGxvd2VkRGVwZW5kZW5jaWVzLCBtb2R1bGVzKSB7XG4gIGNvbnN0IHJhbmdlID0gYWxsb3dlZERlcGVuZGVuY2llcy5nZXQocmVmZXJlbmNlLm1vZHVsZSlcblxuICBpZiAoIXJhbmdlKSBpbnZhbGlkQ29udHJhY3QoYENhbm9uaWNhbCBtb2R1bGUgJyR7cmVjb3JkLmlkZW50aXR5fScgdXNlcyB1bmRlY2xhcmVkIGRlcGVuZGVuY3kgJyR7cmVmZXJlbmNlLm1vZHVsZX0nLmApXG4gIGNvbnN0IHZlcnNpb25zID0gLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBTdGRsaWJDb250cmFjdE1vZHVsZT59ICovIChtb2R1bGVzLmdldChyZWZlcmVuY2UubW9kdWxlKSlcbiAgY29uc3QgbWF0Y2hlcyA9IFsuLi52ZXJzaW9ucy52YWx1ZXMoKV0uZmlsdGVyKChtb2R1bGUpID0+XG4gICAgc3RkbGliVmVyc2lvblNhdGlzZmllcygvKiogQHR5cGUge1ZlcnNpb25UdXBsZX0gKi8gKHBhcnNlU3RkbGliVmVyc2lvbihtb2R1bGUudmVyc2lvbikpLCByYW5nZSkpXG4gIGNvbnN0IGRlY2xhcmF0aW9ucyA9IGtpbmQgPT0gXCJyZXNvdXJjZVwiID8gbWF0Y2hlcy5mbGF0TWFwKCh7cmVzb3VyY2VzfSkgPT4gcmVzb3VyY2VzKSA6IG1hdGNoZXMuZmxhdE1hcCgoe2ZhaWx1cmVzfSkgPT4gZmFpbHVyZXMpXG5cbiAgaWYgKCFkZWNsYXJhdGlvbnMuc29tZSgoe25hbWV9KSA9PiBuYW1lID09IHJlZmVyZW5jZS5uYW1lKSkge1xuICAgIGludmFsaWRDb250cmFjdChgQ2Fub25pY2FsICR7a2luZH0gJyR7cmVmZXJlbmNlLm1vZHVsZX0uJHtyZWZlcmVuY2UubmFtZX0nIGlzIG5vdCBkZWNsYXJlZCBieSBhIGNvbXBhdGlibGUgZGVwZW5kZW5jeS5gKVxuICB9XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBvbmUgbG9jYWwgb3IgZGVwZW5kZW5jeS1xdWFsaWZpZWQgZGVjbGFyYXRpb24gcmVmZXJlbmNlLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgcmVmZXJlbmNlLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gbG9jYWxOYW1lcyAtIERlY2xhcmVkIGxvY2FsIG5hbWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBEaWFnbm9zdGljIHN1YmplY3QuXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2V9IERldGFjaGVkIHJlZmVyZW5jZS5cbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplRGVjbGFyYXRpb25SZWZlcmVuY2UoY2FuZGlkYXRlLCBsb2NhbE5hbWVzLCBzdWJqZWN0KSB7XG4gIGlmICh0eXBlb2YgY2FuZGlkYXRlID09IFwic3RyaW5nXCIgJiYgbG9jYWxOYW1lcy5oYXMoY2FuZGlkYXRlKSkgcmV0dXJuIGNhbmRpZGF0ZVxuICBpZiAoaXNEZWNsYXJhdGlvblJlZmVyZW5jZShjYW5kaWRhdGUpKSByZXR1cm4ge21vZHVsZTogY2FuZGlkYXRlLm1vZHVsZSwgbmFtZTogY2FuZGlkYXRlLm5hbWV9XG4gIHJldHVybiBpbnZhbGlkQ29udHJhY3QoYCR7c3ViamVjdH0gaXMgbm90IGEgZGVjbGFyZWQgbG9jYWwgb3IgcXVhbGlmaWVkIGNhbm9uaWNhbCBkZWNsYXJhdGlvbi5gKVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgYSB0ZXJtaW5hbCBmYWlsdXJlIHJlZmVyZW5jZSBhZnRlciBtZW1iZXJzaGlwIHZhbGlkYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBmYWlsdXJlIHJlZmVyZW5jZS5cbiAqIEByZXR1cm5zIHtzdHJpbmcgfCBDYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gRGV0YWNoZWQgcmVmZXJlbmNlLlxuICovXG5mdW5jdGlvbiBub3JtYWxpemVGYWlsdXJlRmxvd1JlZmVyZW5jZShjYW5kaWRhdGUpIHtcbiAgaWYgKHR5cGVvZiBjYW5kaWRhdGUgPT0gXCJzdHJpbmdcIikgcmV0dXJuIGNhbmRpZGF0ZVxuICBpZiAoaXNEZWNsYXJhdGlvblJlZmVyZW5jZShjYW5kaWRhdGUpKSByZXR1cm4ge21vZHVsZTogY2FuZGlkYXRlLm1vZHVsZSwgbmFtZTogY2FuZGlkYXRlLm5hbWV9XG4gIHJldHVybiBpbnZhbGlkQ29udHJhY3QoXCJSZXNvdXJjZSBmbG93IHRlcm1pbmFsIGZhaWx1cmUgaXMgaW52YWxpZC5cIilcbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGNhbm9uaWNhbCBxdWFsaWZpZWQgZGVjbGFyYXRpb24gcmVmZXJlbmNlLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBDYW5kaWRhdGUgcmVmZXJlbmNlLlxuICogQHJldHVybnMge2NhbmRpZGF0ZSBpcyBDYW5vbmljYWxEZWNsYXJhdGlvblJlZmVyZW5jZX0gV2hldGhlciB0aGUgcmVmZXJlbmNlIGlzIGV4YWN0LlxuICovXG5mdW5jdGlvbiBpc0RlY2xhcmF0aW9uUmVmZXJlbmNlKGNhbmRpZGF0ZSkge1xuICByZXR1cm4gaXNQbGFpbk9iamVjdChjYW5kaWRhdGUpICYmIE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuc29ydCgpLmpvaW4oXCIsXCIpID09IFwibW9kdWxlLG5hbWVcIiAmJlxuICAgIHR5cGVvZiBjYW5kaWRhdGUubW9kdWxlID09IFwic3RyaW5nXCIgJiYgaWRlbnRpdHlQYXR0ZXJuLnRlc3QoY2FuZGlkYXRlLm1vZHVsZSkgJiZcbiAgICB0eXBlb2YgY2FuZGlkYXRlLm5hbWUgPT0gXCJzdHJpbmdcIiAmJiBkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3QoY2FuZGlkYXRlLm5hbWUpXG59XG5cbi8qKlxuICogRW5jb2RlcyBvbmUgZGVjbGFyYXRpb24gcmVmZXJlbmNlIGZvciBlcXVhbGl0eSBjaGVja3MuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIExvY2FsIG9yIHF1YWxpZmllZCByZWZlcmVuY2UuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTdGFibGUgZXF1YWxpdHkga2V5LlxuICovXG5mdW5jdGlvbiByZWZlcmVuY2VLZXkoY2FuZGlkYXRlKSB7XG4gIHJldHVybiB0eXBlb2YgY2FuZGlkYXRlID09IFwic3RyaW5nXCIgPyBgbG9jYWw6JHtjYW5kaWRhdGV9YCA6IGlzRGVjbGFyYXRpb25SZWZlcmVuY2UoY2FuZGlkYXRlKVxuICAgID8gYCR7Y2FuZGlkYXRlLm1vZHVsZX06JHtjYW5kaWRhdGUubmFtZX1gIDogYGludmFsaWQ6JHtTdHJpbmcoY2FuZGlkYXRlKX1gXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIGEgY2Fub25pY2FsIHR5cGUgZGVub3RlcyBhbiBvd25lZCByZXNvdXJjZS5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgQ2Fub25pY2FsRGVjbGFyYXRpb25SZWZlcmVuY2V9IGNhbmRpZGF0ZSAtIENhbm9uaWNhbCB0eXBlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHR5cGUgaXMgb3duZWQuXG4gKi9cbmZ1bmN0aW9uIGlzT3duZWRDYW5vbmljYWxUeXBlKGNhbmRpZGF0ZSkge1xuICByZXR1cm4gaXNEZWNsYXJhdGlvblJlZmVyZW5jZShjYW5kaWRhdGUpIHx8ICh0eXBlb2YgY2FuZGlkYXRlID09IFwic3RyaW5nXCIgJiYgIXNjYWxhck5hbWVzLmhhcyhjYW5kaWRhdGUpICYmXG4gICAgIWNhbmRpZGF0ZS5zdGFydHNXaXRoKFwib3B0aW9uYWw6XCIpICYmIGNhbmRpZGF0ZSAhPSBcInZvaWRcIilcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIGNsb3NlZCBzZW1hbnRpY3MgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBzZW1hbnRpY3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIC0gT3BlcmF0aW9uIG5hbWUuXG4gKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgc3RyaW5nPn0gQ2xvc2VkIHNlbWFudGljcyBmaWVsZHMuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQ29udHJhY3RTZW1hbnRpY3MoY2FuZGlkYXRlLCBvcGVyYXRpb24pIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkgfHwgT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5zb3J0KCkuam9pbihcIixcIikgIT1cbiAgICBcImJsb2NraW5nLGNsb3NlLGVuY29kaW5nLGVvZixuZXdsaW5lLG93bmVyc2hpcCx0aW1lb3V0XCIpIHtcbiAgICBpbnZhbGlkQ29udHJhY3QoYE9wZXJhdGlvbiAnJHtvcGVyYXRpb259JyByZXF1aXJlcyB0aGUgY2xvc2VkIGNhbm9uaWNhbCBzZW1hbnRpY3MgZmllbGRzLmApXG4gIH1cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+fSAqL1xuICBjb25zdCBzZW1hbnRpY3MgPSB7fVxuXG4gIGZvciAoY29uc3QgW2ZpZWxkLCBhbGxvd2VkXSBvZiBPYmplY3QuZW50cmllcyhzZW1hbnRpY3NWYWx1ZXMpKSB7XG4gICAgY29uc3QgdmFsdWUgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKGNhbmRpZGF0ZVtmaWVsZF0pXG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9IFwic3RyaW5nXCIgfHwgIWFsbG93ZWQuaGFzKHZhbHVlKSkge1xuICAgICAgaW52YWxpZENvbnRyYWN0KGBPcGVyYXRpb24gJyR7b3BlcmF0aW9ufScgZGVjbGFyZXMgYSBub24tY2Fub25pY2FsICcke2ZpZWxkfScgc2VtYW50aWNzIHZhbHVlLmApXG4gICAgfVxuICAgIHNlbWFudGljc1tmaWVsZF0gPSB2YWx1ZVxuICB9XG4gIHJldHVybiBkZWVwRnJlZXplKHNlbWFudGljcylcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIGRlbnNlIG9yZGVyZWQgc2luZ2xlLWZpZWxkIG5hbWVkIGRlY2xhcmF0aW9uIGxpc3QuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBsaXN0LlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBEaWFnbm9zdGljIHN1YmplY3QuXG4gKiBAcmV0dXJucyB7e25hbWU6IHN0cmluZ31bXX0gRGV0YWNoZWQgZGVjbGFyYXRpb25zLlxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZU5hbWVkTGlzdChjYW5kaWRhdGUsIHN1YmplY3QpIHtcbiAgaWYgKCFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlKSkgaW52YWxpZENvbnRyYWN0KGBDYW5vbmljYWwgY29udHJhY3QgJHtzdWJqZWN0fXMgbXVzdCBiZSBhIGRlbnNlIGFycmF5LmApXG4gIGNvbnN0IG5hbWVzID0gbmV3IFNldCgpXG4gIC8qKiBAdHlwZSB7e25hbWU6IHN0cmluZ31bXX0gKi9cbiAgY29uc3QgZGVjbGFyYXRpb25zID0gW11cblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGNhbmRpZGF0ZSkge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChkZWNsYXJhdGlvbikgfHwgT2JqZWN0LmtleXMoZGVjbGFyYXRpb24pLmpvaW4oXCIsXCIpICE9IFwibmFtZVwiIHx8XG4gICAgICB0eXBlb2YgZGVjbGFyYXRpb24ubmFtZSAhPSBcInN0cmluZ1wiIHx8ICFkZWNsYXJhdGlvbk5hbWVQYXR0ZXJuLnRlc3QoZGVjbGFyYXRpb24ubmFtZSkgfHwgbmFtZXMuaGFzKGRlY2xhcmF0aW9uLm5hbWUpKSB7XG4gICAgICBpbnZhbGlkQ29udHJhY3QoYENhbm9uaWNhbCBjb250cmFjdCAke3N1YmplY3R9IGRlY2xhcmF0aW9ucyBtdXN0IGJlIHVuaXF1ZWx5IG5hbWVkLmApXG4gICAgfVxuICAgIG5hbWVzLmFkZCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLm5hbWUpKVxuICAgIGRlY2xhcmF0aW9ucy5wdXNoKHtuYW1lOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLm5hbWUpfSlcbiAgfVxuICByZXR1cm4gZGVjbGFyYXRpb25zXG59XG5cbi8qKlxuICogUmVwb3J0cyBhbiB1bmtub3duIGNhbm9uaWNhbCBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWRlbnRpdHkgLSBVbmtub3duIGlkZW50aXR5LlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiB1bmtub3duTW9kdWxlKGlkZW50aXR5KSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiU1RETElCX01PRFVMRV9VTktOT1dOXCIsIGxhbmd1YWdlOiBcInN0ZGxpYlwiLFxuICAgIG1lc3NhZ2U6IGBTdGFuZGFyZC1saWJyYXJ5IG1vZHVsZSAnJHtpZGVudGl0eX0nIGlzIG5vdCBhIHJlZ2lzdGVyZWQgY2Fub25pY2FsIGNvbnRyYWN0LmB9KVxufVxuXG4vKipcbiAqIFJlcG9ydHMgb25lIG1hbGZvcm1lZCB2ZXJzaW9uIHJhbmdlLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBtYWxmb3JtZWRSYW5nZSgpIHtcbiAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7Y29kZTogXCJTVERMSUJfVkVSU0lPTl9NQUxGT1JNRURcIiwgbGFuZ3VhZ2U6IFwic3RkbGliXCIsXG4gICAgbWVzc2FnZTogXCJTdGFuZGFyZC1saWJyYXJ5IHZlcnNpb24gcmFuZ2VzIHVzZSBYLCBYLlksIG9yIFguWS5aIHdpdGhvdXQgbGVhZGluZyB6ZXJvcyBvciBwcmVyZWxlYXNlIGxhYmVscy5cIn0pXG59XG5cbi8qKlxuICogUmVwb3J0cyBvbmUgdW5zYXRpc2ZpYWJsZSB2ZXJzaW9uIHJhbmdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGlkZW50aXR5IC0gQ29uc3RyYWluZWQgbW9kdWxlIGlkZW50aXR5LlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBpbmNvbXBhdGlibGVWZXJzaW9uKGlkZW50aXR5KSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiU1RETElCX1ZFUlNJT05fSU5DT01QQVRJQkxFXCIsIGxhbmd1YWdlOiBcInN0ZGxpYlwiLFxuICAgIG1lc3NhZ2U6IGBObyByZWdpc3RlcmVkIHZlcnNpb24gb2YgJyR7aWRlbnRpdHl9JyBzYXRpc2ZpZXMgdGhlIGRlY2xhcmVkIHN0YW5kYXJkLWxpYnJhcnkgdmVyc2lvbiByYW5nZS5gfSlcbn1cblxuLyoqXG4gKiBSYWlzZXMgb25lIHN0YWJsZSBjYW5vbmljYWwgY29udHJhY3QgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRGlhZ25vc3RpYyBtZXNzYWdlLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBpbnZhbGlkQ29udHJhY3QobWVzc2FnZSkge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlNURExJQl9DT05UUkFDVF9JTlZBTElEXCIsIGxhbmd1YWdlOiBcInN0ZGxpYlwiLCBtZXNzYWdlfSlcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyBvbmUgZXhhY3QgZmllbGQgc2V0LlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gdmFsdWUgLSBDYW5kaWRhdGUgb2JqZWN0LlxuICogQHBhcmFtIHtzdHJpbmdbXX0ga2V5cyAtIFJlcXVpcmVkIGtleXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ViamVjdCAtIERpYWdub3N0aWMgc3ViamVjdC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZXF1aXJlS2V5cyh2YWx1ZSwga2V5cywgc3ViamVjdCkge1xuICBpZiAoT2JqZWN0LmtleXModmFsdWUpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBbLi4ua2V5c10uc29ydCgpLmpvaW4oXCIsXCIpKSBpbnZhbGlkQ29udHJhY3QoYEludmFsaWQgJHtzdWJqZWN0fSBmaWVsZHMuYClcbn1cblxuLyoqXG4gKiBDaGVja3MgYW4gb3JkZXJlZCBkZW5zZSBhcnJheS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgYXJyYXkuXG4gKiBAcmV0dXJucyB7dmFsdWUgaXMgdW5rbm93bltdfSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBkZW5zZS5cbiAqL1xuZnVuY3Rpb24gaXNEZW5zZUFycmF5KHZhbHVlKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KHZhbHVlKSAmJiB2YWx1ZS5ldmVyeSgoX2l0ZW0sIGluZGV4KSA9PiBPYmplY3QuaGFzT3duKHZhbHVlLCBpbmRleCkpXG59XG5cbi8qKlxuICogQ2hlY2tzIGZvciBhbiBvcmRpbmFyeSBzdHJpbmcta2V5ZWQgb2JqZWN0LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSB2YWx1ZS5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9PSBudWxsICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJlxuICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT0gT2JqZWN0LnByb3RvdHlwZVxufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGZyZWV6ZXMgYSBkZXRhY2hlZCB2YWx1ZS5cbiAqIEB0ZW1wbGF0ZSB7b2JqZWN0fSBWYWx1ZVxuICogQHBhcmFtIHtWYWx1ZX0gdmFsdWUgLSBPYmplY3QgdG8gZnJlZXplLlxuICogQHJldHVybnMge1JlYWRvbmx5PFZhbHVlPn0gRnJvemVuIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gZGVlcEZyZWV6ZSh2YWx1ZSkge1xuICBmb3IgKGNvbnN0IGNoaWxkIG9mIE9iamVjdC52YWx1ZXModmFsdWUpKSB7XG4gICAgaWYgKGNoaWxkICYmIHR5cGVvZiBjaGlsZCA9PSBcIm9iamVjdFwiICYmICFPYmplY3QuaXNGcm96ZW4oY2hpbGQpKSBkZWVwRnJlZXplKGNoaWxkKVxuICB9XG4gIHJldHVybiBPYmplY3QuZnJlZXplKHZhbHVlKVxufVxuXG4vKiogQHR5cGUge1JlYWRvbmx5PFN0ZGxpYkNvbnRyYWN0UmVnaXN0cnk+fSAqL1xuY29uc3QgYnVpbHRpblJlZ2lzdHJ5ID0gY3JlYXRlU3RkbGliQ29udHJhY3RSZWdpc3RyeSgpXG4iXX0=
|