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,1309 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { isDenseArray } from "../array.js";
|
|
3
|
+
import { isSafeArtifactPath, isSafeSourcePath } from "../artifact-path.js";
|
|
4
|
+
import { createGeneratedArtifactSet } from "../artifacts.js";
|
|
5
|
+
import { SemantifoldDiagnostic, unsupportedCapability, unsupportedRole } from "../diagnostic.js";
|
|
6
|
+
import { parseProgramSource } from "../frontends/program.js";
|
|
7
|
+
import { languageRegistry } from "../language-registry.js";
|
|
8
|
+
import { finalizeMapping, toSourceMapV3 } from "../mapping.js";
|
|
9
|
+
import { createCoordinateIndex, indexedPointAt, moduleLocation } from "../semantic/location.js";
|
|
10
|
+
import { semanticEntries } from "../semantic/provenance.js";
|
|
11
|
+
import { listStdlibModules, parseStdlibVersionRange } from "../semantic/stdlib.js";
|
|
12
|
+
import { moduleUncheckedErrorEffects } from "../semantic/validate.js";
|
|
13
|
+
import { negotiateStdlibProviders } from "../stdlib-negotiation.js";
|
|
14
|
+
import { stdlibFacadeProgramDescriptor, stdlibFacadeRegistry } from "../stdlib-facades.js";
|
|
15
|
+
import { stdlibProviderRegistry } from "../stdlib-providers.js";
|
|
16
|
+
import { preflightEffectCapabilities } from "./effects.js";
|
|
17
|
+
import { validateTargetBindingIdentifier, validateTargetIdentifier, validateTargetTypeIdentifier } from "./identifiers.js";
|
|
18
|
+
import { generateStdlibProviderContent } from "./stdlib-support.js";
|
|
19
|
+
import { validateBackendModule } from "./shared.js";
|
|
20
|
+
import { programImportName, SourceWriter } from "./writer.js";
|
|
21
|
+
/** @type {Readonly<Set<import("../semantic/types.js").SemanticLanguage>>} */
|
|
22
|
+
const programTargets = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
23
|
+
/** @type {Readonly<Set<import("../semantic/types.js").BackendLanguage>>} */
|
|
24
|
+
const programApplicationTargets = new Set(["android", "ios"]);
|
|
25
|
+
/**
|
|
26
|
+
* Validates and prepares a complete semantic program for a non-text backend without allocating a writer.
|
|
27
|
+
* @param {object} input - Backend preflight request.
|
|
28
|
+
* @param {import("../semantic/types.js").SemanticLanguage} input.backendLanguage - Existing semantic backend profile to enforce.
|
|
29
|
+
* @param {import("../semantic/types.js").BackendLanguage} input.diagnosticLanguage - Public target identity for capability failures.
|
|
30
|
+
* @param {import("../semantic/types.js").SemanticProgram} input.program - Complete candidate program.
|
|
31
|
+
* @param {Readonly<Set<import("../semantic/types.js").SemanticLanguage>>} [input.sourceLanguages] - Accepted source provenance languages.
|
|
32
|
+
* @returns {{modules: import("../semantic/types.js").SemanticModule[], program: import("../semantic/types.js").SemanticProgram, sources: {content: string, filename: string, language?: import("../semantic/types.js").SemanticLanguage}[]}} Prepared immutable-input views.
|
|
33
|
+
*/
|
|
34
|
+
export function preflightSemanticProgram({ backendLanguage, diagnosticLanguage, program: candidate, sourceLanguages }) {
|
|
35
|
+
try {
|
|
36
|
+
const program = validateProgram(candidate, backendLanguage, sourceLanguages);
|
|
37
|
+
const modules = prepareEmissionModules(program, backendLanguage);
|
|
38
|
+
validateProgramSourceOwnership(program, backendLanguage);
|
|
39
|
+
const sources = program.sources.map((source) => {
|
|
40
|
+
if (source.content === null)
|
|
41
|
+
invalidProgramGeneration(`Program source '${source.filename}' has no retained content.`);
|
|
42
|
+
return { content: source.content, filename: source.filename, ...(source.language ? { language: source.language } : {}) };
|
|
43
|
+
});
|
|
44
|
+
return { modules, program, sources };
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
if (error instanceof SemantifoldDiagnostic && error.code == "UNSUPPORTED_CAPABILITY" &&
|
|
48
|
+
error.language != diagnosticLanguage) {
|
|
49
|
+
throw new SemantifoldDiagnostic({
|
|
50
|
+
cause: error,
|
|
51
|
+
code: error.code,
|
|
52
|
+
language: diagnosticLanguage,
|
|
53
|
+
location: error.location,
|
|
54
|
+
message: error.detail
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
throw error;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Generates a complete deterministic mapped artifact set for one semantic program.
|
|
62
|
+
* @param {object} input - Program generation request.
|
|
63
|
+
* @param {import("../semantic/types.js").BackendLanguage} input.language - Registered program target.
|
|
64
|
+
* @param {import("../semantic/types.js").SemanticProgram} input.program - Complete semantic program.
|
|
65
|
+
* @param {"text" | "application"} [input.role] - Explicit artifact role; omitted preserves text generation.
|
|
66
|
+
* @param {import("../semantic/types.js").IosApplicationConfigurationInput | import("../semantic/types.js").AndroidApplicationConfigurationInput} [input.configuration] - Application configuration.
|
|
67
|
+
* @param {import("../semantic/types.js").IosApplicationAssetInput[] | import("../semantic/types.js").AndroidApplicationInputFile[]} [input.assets] - Exact caller assets.
|
|
68
|
+
* @param {import("../semantic/types.js").AndroidApplicationInputFile[]} [input.resources] - Exact Android caller resources.
|
|
69
|
+
* @returns {import("../semantic/types.js").GeneratedArtifactSet} Transactionally validated artifact set.
|
|
70
|
+
*/
|
|
71
|
+
export function generateProgramArtifacts(input) {
|
|
72
|
+
if (!isPlainObject(input) || typeof input.language != "string")
|
|
73
|
+
invalidProgramGeneration("Program generation requires a target language and program.");
|
|
74
|
+
const role = input.role ?? "text";
|
|
75
|
+
if (role != "text" && role != "application")
|
|
76
|
+
invalidProgramGeneration("Program artifact role must be 'text' or 'application'.");
|
|
77
|
+
languageRegistry.record(input.language);
|
|
78
|
+
if (role == "application") {
|
|
79
|
+
if (!programApplicationTargets.has(input.language))
|
|
80
|
+
unsupportedRole(input.language, "multi-file application backend");
|
|
81
|
+
const backend = languageRegistry.resolve(input.language, "applicationBackend");
|
|
82
|
+
return createGeneratedArtifactSet(backend(input));
|
|
83
|
+
}
|
|
84
|
+
if (!programTargets.has(/** @type {import("../semantic/types.js").SemanticLanguage} */ (input.language))) {
|
|
85
|
+
unsupportedRole(input.language, "multi-file text backend");
|
|
86
|
+
}
|
|
87
|
+
const language = /** @type {import("../semantic/types.js").SemanticLanguage} */ (input.language);
|
|
88
|
+
const program = validateProgram(input.program, language);
|
|
89
|
+
const linking = planStdlibLinking(program, language);
|
|
90
|
+
const emissionModules = prepareEmissionModules(program, language, linking);
|
|
91
|
+
validateProgramSourceOwnership(program, language);
|
|
92
|
+
const paths = planModulePaths(program, language, linking);
|
|
93
|
+
const sources = program.sources.map((source) => {
|
|
94
|
+
if (source.content === null)
|
|
95
|
+
invalidProgramGeneration(`Program source '${source.filename}' has no retained content.`);
|
|
96
|
+
return { content: source.content, filename: source.filename, ...(source.language ? { language: source.language } : {}) };
|
|
97
|
+
});
|
|
98
|
+
const backend = /** @type {typeof import("./javascript.js").generateJavaScript} */ (languageRegistry.resolve(language, "textBackend"));
|
|
99
|
+
const mediaType = languageRegistry.record(language).mediaType;
|
|
100
|
+
/** @type {import("../semantic/types.js").GeneratedSetArtifact[]} */
|
|
101
|
+
const artifacts = language == "javascript" || language == "typescript" ? [{
|
|
102
|
+
content: "{\n \"type\": \"module\"\n}\n",
|
|
103
|
+
contentKind: /** @type {const} */ ("text"),
|
|
104
|
+
mediaType: "application/json",
|
|
105
|
+
ownership: /** @type {const} */ ("generated"),
|
|
106
|
+
path: "package.json",
|
|
107
|
+
provenance: {
|
|
108
|
+
kind: /** @type {const} */ ("synthetic"),
|
|
109
|
+
reason: "Declares the generated JavaScript-family artifact set as canonical ESM.",
|
|
110
|
+
relatedOrigins: []
|
|
111
|
+
},
|
|
112
|
+
role: "manifest"
|
|
113
|
+
}] : [];
|
|
114
|
+
if (linking && language != "java") {
|
|
115
|
+
for (const provider of linking.negotiation.providers) {
|
|
116
|
+
const record = /** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (linking.records.get(provider.module));
|
|
117
|
+
artifacts.push({
|
|
118
|
+
content: generateStdlibProviderContent(/** @type {"php" | "ruby" | "javascript" | "typescript"} */ (language), [...provider.operations], provider.module),
|
|
119
|
+
contentKind: /** @type {const} */ ("text"),
|
|
120
|
+
mediaType: record.artifact.mediaType,
|
|
121
|
+
ownership: /** @type {const} */ ("generated"),
|
|
122
|
+
path: record.artifact.path,
|
|
123
|
+
provenance: {
|
|
124
|
+
kind: /** @type {const} */ ("synthetic"),
|
|
125
|
+
reason: `semantifold-stdlib-provider:${record.identity}`,
|
|
126
|
+
relatedOrigins: []
|
|
127
|
+
},
|
|
128
|
+
role: /** @type {const} */ ("support")
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
for (const emissionModule of emissionModules) {
|
|
133
|
+
const moduleId = /** @type {string} */ (Reflect.get(emissionModule, "id"));
|
|
134
|
+
const filename = /** @type {string} */ (paths.get(moduleId));
|
|
135
|
+
const writer = new SourceWriter({
|
|
136
|
+
filename,
|
|
137
|
+
language,
|
|
138
|
+
module: emissionModule,
|
|
139
|
+
program,
|
|
140
|
+
programPaths: paths,
|
|
141
|
+
sources,
|
|
142
|
+
...(linking && emissionModule.capabilities !== undefined ? {
|
|
143
|
+
stdlibProviderEntries: Object.fromEntries((linking.usedOperationsByModule.get(moduleId) ?? []).map(({ module, operation }) => [
|
|
144
|
+
qualifiedOperationKey(module, operation),
|
|
145
|
+
/** @type {string} */ (linking.records.get(module)?.nativeEntries[operation])
|
|
146
|
+
])),
|
|
147
|
+
stdlibProviderImports: language == "java" || language == "javascript" || language == "typescript" ?
|
|
148
|
+
linking.providerImportsByModule.get(moduleId) : undefined,
|
|
149
|
+
stdlibProviderPaths: linking.providerPathsByModule.get(moduleId),
|
|
150
|
+
...(language == "java" ? {
|
|
151
|
+
stdlibProviderOwnerModule: /** @type {string} */ (linking.ownerModuleId),
|
|
152
|
+
stdlibProviderShims: moduleId == linking.ownerModuleId ? linking.usedOperations.map(({ operation }) => operation) : undefined
|
|
153
|
+
} : {})
|
|
154
|
+
} : {})
|
|
155
|
+
});
|
|
156
|
+
backend(emissionModule, writer);
|
|
157
|
+
const mapping = finalizeMapping(writer.finish());
|
|
158
|
+
artifacts.push({
|
|
159
|
+
content: mapping.generated.content,
|
|
160
|
+
contentKind: /** @type {const} */ ("text"),
|
|
161
|
+
mediaType: /** @type {string} */ (mediaType),
|
|
162
|
+
ownership: /** @type {const} */ ("generated"),
|
|
163
|
+
path: filename,
|
|
164
|
+
provenance: {
|
|
165
|
+
kind: /** @type {const} */ ("text"),
|
|
166
|
+
mapping,
|
|
167
|
+
sourceMap: toSourceMapV3(mapping),
|
|
168
|
+
sourceMapFilename: `${filename}.map`
|
|
169
|
+
},
|
|
170
|
+
role: /** @type {import("../semantic/types.js").GeneratedArtifactRole} */ (moduleId == program.entryModule ? "entry" : Reflect.get(emissionModule, "stdlibFacade") ? "support" : "source")
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
return createGeneratedArtifactSet({
|
|
174
|
+
artifacts,
|
|
175
|
+
...(linking || program.stdlibFacades ? { metadata: stdlibLinkMetadata(linking, paths, program.stdlibFacades) } : {}),
|
|
176
|
+
target: language
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* @typedef StdlibProgramLinking
|
|
181
|
+
* @property {import("../stdlib-negotiation.js").StdlibNegotiationResult} negotiation - Negotiated provider closure.
|
|
182
|
+
* @property {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} records - Materialized provider records by canonical module.
|
|
183
|
+
* @property {QualifiedStdlibOperation[]} usedOperations - Program-wide used canonical operations in stable order.
|
|
184
|
+
* @property {Map<string, QualifiedStdlibOperation[]>} usedOperationsByModule - Used canonical operations by program module identity.
|
|
185
|
+
* @property {Map<string, string[]>} providerImportsByModule - Ordered provider import names by module identity.
|
|
186
|
+
* @property {Map<string, string[]>} providerPathsByModule - Provider artifact closure by program module identity.
|
|
187
|
+
* @property {string | null} ownerModuleId - Java target: first operation-using module identity hosting the shared support; null for artifact-materializing targets.
|
|
188
|
+
*/
|
|
189
|
+
/**
|
|
190
|
+
* @typedef QualifiedStdlibOperation
|
|
191
|
+
* @property {string} module - Canonical module identity.
|
|
192
|
+
* @property {string} operation - Canonical operation name.
|
|
193
|
+
*/
|
|
194
|
+
/**
|
|
195
|
+
* Plans the linked stdlib provider for one program, or reports that no operation is used.
|
|
196
|
+
* Java resolves the same negotiated provider record but hosts its support in the first
|
|
197
|
+
* operation-using module instead of a separate provider artifact.
|
|
198
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
199
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
200
|
+
* @returns {StdlibProgramLinking | null} Linking plan, or null when nothing is used.
|
|
201
|
+
*/
|
|
202
|
+
function planStdlibLinking(program, language) {
|
|
203
|
+
const { programWide, usedOperationsByModule } = collectUsedEffectOperations(program);
|
|
204
|
+
if (programWide.length == 0)
|
|
205
|
+
return null;
|
|
206
|
+
const contracts = program.stdlibContracts ?? [/** @type {{identity: string, contractVersion?: string}} */ (program.stdlibContract)];
|
|
207
|
+
const contractsByIdentity = new Map(contracts.map((contract) => [contract.identity, contract]));
|
|
208
|
+
const requirementsByModule = new Map();
|
|
209
|
+
for (const qualified of programWide) {
|
|
210
|
+
const requirement = requirementsByModule.get(qualified.module) ?? [];
|
|
211
|
+
requirement.push(qualified.operation);
|
|
212
|
+
requirementsByModule.set(qualified.module, requirement);
|
|
213
|
+
}
|
|
214
|
+
const negotiation = negotiateStdlibProviders({
|
|
215
|
+
requirements: [...requirementsByModule].map(([module, operations]) => {
|
|
216
|
+
const contract = contractsByIdentity.get(module);
|
|
217
|
+
if (!contract)
|
|
218
|
+
throw new SemantifoldDiagnostic({
|
|
219
|
+
code: "STDLIB_LINK_FAILURE",
|
|
220
|
+
language,
|
|
221
|
+
message: `Reachable canonical operation '${module}.${operations[0]}' has no declared standard-library contract.`
|
|
222
|
+
});
|
|
223
|
+
return { module, operations, ...(contract.contractVersion !== undefined ? { range: contract.contractVersion } : {}) };
|
|
224
|
+
}),
|
|
225
|
+
target: language
|
|
226
|
+
});
|
|
227
|
+
/** @type {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} */
|
|
228
|
+
const records = new Map();
|
|
229
|
+
for (const selected of negotiation.modules) {
|
|
230
|
+
const candidates = stdlibProviderRegistry.providersFor(language, selected.identity, selected.version);
|
|
231
|
+
if (candidates.length != 1) {
|
|
232
|
+
throw new SemantifoldDiagnostic({
|
|
233
|
+
code: "STDLIB_LINK_FAILURE",
|
|
234
|
+
language,
|
|
235
|
+
message: `Expected exactly one registered stdlib provider for '${selected.identity}' on '${language}'.`
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
records.set(selected.identity, /** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (candidates[0]));
|
|
239
|
+
}
|
|
240
|
+
const ownerModuleId = language == "java"
|
|
241
|
+
? program.modules.map((module) => module.id).find((id) => (usedOperationsByModule.get(id) ?? []).length > 0)
|
|
242
|
+
: null;
|
|
243
|
+
if (ownerModuleId === undefined)
|
|
244
|
+
throw new SemantifoldDiagnostic({
|
|
245
|
+
code: "STDLIB_LINK_FAILURE",
|
|
246
|
+
language,
|
|
247
|
+
message: "Java program linking requires one module using canonical operations."
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
negotiation,
|
|
251
|
+
ownerModuleId,
|
|
252
|
+
providerImportsByModule: collectProviderImports(program, negotiation, records, usedOperationsByModule, language, ownerModuleId),
|
|
253
|
+
providerPathsByModule: collectProviderPaths(negotiation, records, usedOperationsByModule),
|
|
254
|
+
records,
|
|
255
|
+
usedOperations: [...programWide],
|
|
256
|
+
usedOperationsByModule
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Selects the exact provider/type dependency closure required by each emitting program module.
|
|
261
|
+
* @param {import("../stdlib-negotiation.js").StdlibNegotiationResult} negotiation - Negotiated program closure.
|
|
262
|
+
* @param {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} records - Selected provider records.
|
|
263
|
+
* @param {Map<string, QualifiedStdlibOperation[]>} usedOperationsByModule - Reachable operations by program module.
|
|
264
|
+
* @returns {Map<string, string[]>} Ordered provider paths by program module.
|
|
265
|
+
*/
|
|
266
|
+
function collectProviderPaths(negotiation, records, usedOperationsByModule) {
|
|
267
|
+
const paths = new Map();
|
|
268
|
+
for (const [moduleId, operations] of usedOperationsByModule) {
|
|
269
|
+
const selected = new Set(operations.map(({ module }) => module));
|
|
270
|
+
let changed = true;
|
|
271
|
+
while (changed) {
|
|
272
|
+
changed = false;
|
|
273
|
+
for (const module of [...selected]) {
|
|
274
|
+
for (const dependency of records.get(module)?.dependencies ?? []) {
|
|
275
|
+
if (!selected.has(dependency.module)) {
|
|
276
|
+
selected.add(dependency.module);
|
|
277
|
+
changed = true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
paths.set(moduleId, negotiation.providers.filter(({ module }) => selected.has(module)).map(({ module }) =>
|
|
283
|
+
/** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (records.get(module)).artifact.path));
|
|
284
|
+
}
|
|
285
|
+
return paths;
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Collects the canonical operations invoked by each program module in stable order.
|
|
289
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
290
|
+
* @returns {{programWide: QualifiedStdlibOperation[], usedOperationsByModule: Map<string, QualifiedStdlibOperation[]>}} Used operations.
|
|
291
|
+
*/
|
|
292
|
+
function collectUsedEffectOperations(program) {
|
|
293
|
+
/** @type {Map<string, QualifiedStdlibOperation[]>} */
|
|
294
|
+
const usedOperationsByModule = new Map();
|
|
295
|
+
/** @type {Map<string, QualifiedStdlibOperation>} */
|
|
296
|
+
const programWide = new Map();
|
|
297
|
+
/** @type {Map<string, {body: unknown, module: import("../semantic/types.js").SemanticProgramModule}>} */
|
|
298
|
+
const bodies = new Map();
|
|
299
|
+
for (const module of program.modules) {
|
|
300
|
+
for (const declaration of module.functions)
|
|
301
|
+
bodies.set(/** @type {string} */ (declaration.id), { body: declaration.body, module });
|
|
302
|
+
for (const declaration of module.classes ?? []) {
|
|
303
|
+
bodies.set(/** @type {string} */ (declaration.constructor.id), { body: declaration.constructor.body, module });
|
|
304
|
+
for (const method of declaration.methods)
|
|
305
|
+
bodies.set(/** @type {string} */ (method.id), { body: method.body, module });
|
|
306
|
+
}
|
|
307
|
+
usedOperationsByModule.set(module.id, []);
|
|
308
|
+
}
|
|
309
|
+
const entryModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (program.modules.find(({ id }) => id == program.entryModule));
|
|
310
|
+
/** @type {{body: unknown, module: import("../semantic/types.js").SemanticProgramModule}[]} */
|
|
311
|
+
const pending = [{ body: entryModule.entryPoint?.body, module: entryModule }];
|
|
312
|
+
const reachedDeclarations = new Set();
|
|
313
|
+
while (pending.length > 0) {
|
|
314
|
+
const current = /** @type {{body: unknown, module: import("../semantic/types.js").SemanticProgramModule}} */ (pending.shift());
|
|
315
|
+
const operationNames = new Map(current.module.capabilities?.flatMap((capability) => capability.operations.map((operation) => [operation.id, { module: capability.authorityId, operation: operation.name }])) ?? []);
|
|
316
|
+
const seen = new Set();
|
|
317
|
+
/**
|
|
318
|
+
* Visits one reachable semantic subtree.
|
|
319
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
320
|
+
*/
|
|
321
|
+
const visit = (value) => {
|
|
322
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
323
|
+
return;
|
|
324
|
+
seen.add(value);
|
|
325
|
+
if (!Array.isArray(value)) {
|
|
326
|
+
const kind = Reflect.get(value, "kind");
|
|
327
|
+
if (kind == "EffectCallExpression") {
|
|
328
|
+
const operation = Reflect.get(value, "operation");
|
|
329
|
+
if (typeof operation == "string") {
|
|
330
|
+
const qualified = operationNames.get(operation);
|
|
331
|
+
if (qualified !== undefined) {
|
|
332
|
+
const key = qualifiedOperationKey(qualified.module, qualified.operation);
|
|
333
|
+
const moduleOperations = /** @type {QualifiedStdlibOperation[]} */ (usedOperationsByModule.get(current.module.id));
|
|
334
|
+
if (!moduleOperations.some((item) => qualifiedOperationKey(item.module, item.operation) == key))
|
|
335
|
+
moduleOperations.push(qualified);
|
|
336
|
+
programWide.set(key, qualified);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
const declarationId = isPlainObject(Reflect.get(value, "resolution"))
|
|
341
|
+
? Reflect.get(Reflect.get(value, "resolution"), "declarationId") : undefined;
|
|
342
|
+
if (typeof declarationId == "string" && !reachedDeclarations.has(declarationId)) {
|
|
343
|
+
const declaration = bodies.get(declarationId);
|
|
344
|
+
if (declaration) {
|
|
345
|
+
reachedDeclarations.add(declarationId);
|
|
346
|
+
pending.push(declaration);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
for (const [key, child] of Object.entries(value)) {
|
|
350
|
+
if (["capabilities", "location", "provenance", "resolution", "sourceProvenance"].includes(key))
|
|
351
|
+
continue;
|
|
352
|
+
visit(child);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
else
|
|
356
|
+
for (const child of value)
|
|
357
|
+
visit(child);
|
|
358
|
+
};
|
|
359
|
+
visit(current.body);
|
|
360
|
+
}
|
|
361
|
+
for (const operations of usedOperationsByModule.values()) {
|
|
362
|
+
operations.sort((left, right) => qualifiedOperationKey(left.module, left.operation)
|
|
363
|
+
.localeCompare(qualifiedOperationKey(right.module, right.operation), "en"));
|
|
364
|
+
}
|
|
365
|
+
return { programWide: [...programWide.values()].sort((left, right) => qualifiedOperationKey(left.module, left.operation)
|
|
366
|
+
.localeCompare(qualifiedOperationKey(right.module, right.operation), "en")), usedOperationsByModule };
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Builds an unambiguous internal key for one canonical operation authority.
|
|
370
|
+
* @param {string} module - Canonical module identity.
|
|
371
|
+
* @param {string} operation - Canonical operation name.
|
|
372
|
+
* @returns {string} Qualified internal key.
|
|
373
|
+
*/
|
|
374
|
+
function qualifiedOperationKey(module, operation) {
|
|
375
|
+
return `${module}\u0000${operation}`;
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Collects the ordered provider import names each module must pull from the linked provider.
|
|
379
|
+
* Java modules list referenced capability type names only; the owner lists none.
|
|
380
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
381
|
+
* @param {import("../stdlib-negotiation.js").StdlibNegotiationResult} negotiation - Negotiated closure.
|
|
382
|
+
* @param {Map<string, import("../stdlib-providers.js").StdlibProviderRecord>} records - Provider records by canonical module.
|
|
383
|
+
* @param {Map<string, QualifiedStdlibOperation[]>} usedOperationsByModule - Used canonical operations by module identity.
|
|
384
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
385
|
+
* @param {string | null} [ownerModuleId] - Java owner module identity.
|
|
386
|
+
* @returns {Map<string, string[]>} Ordered provider import names by module identity.
|
|
387
|
+
*/
|
|
388
|
+
function collectProviderImports(program, negotiation, records, usedOperationsByModule, language, ownerModuleId = null) {
|
|
389
|
+
/** @type {Map<string, string[]>} */
|
|
390
|
+
const providerImportsByModule = new Map();
|
|
391
|
+
for (const module of program.modules) {
|
|
392
|
+
if (module.capabilities === undefined)
|
|
393
|
+
continue;
|
|
394
|
+
const used = new Set((usedOperationsByModule.get(module.id) ?? []).map(({ module: owner, operation }) => qualifiedOperationKey(owner, operation)));
|
|
395
|
+
/** @type {Set<string>} */
|
|
396
|
+
const surface = new Set();
|
|
397
|
+
/** @type {Map<string, string>} */
|
|
398
|
+
const resourceNameById = new Map();
|
|
399
|
+
/** @type {Map<string, string>} */
|
|
400
|
+
const declarationNames = new Map((module.records ?? []).map((declaration) => [/** @type {string} */ (declaration.id), declaration.name]));
|
|
401
|
+
for (const declaration of module.errors ?? []) {
|
|
402
|
+
declarationNames.set(/** @type {string} */ (declaration.id), declaration.name);
|
|
403
|
+
}
|
|
404
|
+
for (const capability of module.capabilities) {
|
|
405
|
+
for (const resource of capability.resources) {
|
|
406
|
+
surface.add(resource.name);
|
|
407
|
+
resourceNameById.set(resource.id, resource.name);
|
|
408
|
+
}
|
|
409
|
+
for (const failure of capability.failures) {
|
|
410
|
+
surface.add(failure.name);
|
|
411
|
+
declarationNames.set(failure.id, failure.name);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
const referenced = new Set();
|
|
415
|
+
const seen = new Set();
|
|
416
|
+
/**
|
|
417
|
+
* Visits one semantic value.
|
|
418
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
419
|
+
* @returns {void}
|
|
420
|
+
*/
|
|
421
|
+
const visit = (value) => {
|
|
422
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
423
|
+
return;
|
|
424
|
+
seen.add(value);
|
|
425
|
+
if (!Array.isArray(value)) {
|
|
426
|
+
const kind = Reflect.get(value, "kind");
|
|
427
|
+
if (kind == "OwnedResourceType") {
|
|
428
|
+
const resourceId = Reflect.get(value, "resourceId");
|
|
429
|
+
if (typeof resourceId == "string") {
|
|
430
|
+
const name = resourceNameById.get(resourceId);
|
|
431
|
+
if (name !== undefined)
|
|
432
|
+
referenced.add(name);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
else if (kind == "ReferenceType" || kind == "OwnedReferenceType" || kind == "ErrorType") {
|
|
436
|
+
const declarationId = Reflect.get(value, "declarationId");
|
|
437
|
+
if (typeof declarationId == "string") {
|
|
438
|
+
const name = declarationNames.get(declarationId);
|
|
439
|
+
if (name !== undefined && surface.has(name))
|
|
440
|
+
referenced.add(name);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
for (const [key, child] of Object.entries(value)) {
|
|
444
|
+
if (key == "capabilities" || key == "location" || key == "sourceProvenance")
|
|
445
|
+
continue;
|
|
446
|
+
visit(child);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
else
|
|
450
|
+
for (const child of value)
|
|
451
|
+
visit(child);
|
|
452
|
+
};
|
|
453
|
+
visit(module);
|
|
454
|
+
const names = [];
|
|
455
|
+
if (language != "java" || module.id != ownerModuleId) {
|
|
456
|
+
for (const capability of module.capabilities) {
|
|
457
|
+
for (const resource of capability.resources)
|
|
458
|
+
if (referenced.has(resource.name))
|
|
459
|
+
names.push(resource.name);
|
|
460
|
+
for (const failure of capability.failures)
|
|
461
|
+
if (referenced.has(failure.name))
|
|
462
|
+
names.push(failure.name);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
if (language != "java") {
|
|
466
|
+
for (const provider of negotiation.providers) {
|
|
467
|
+
const record = records.get(provider.module);
|
|
468
|
+
for (const operation of provider.operations) {
|
|
469
|
+
if (used.has(qualifiedOperationKey(provider.module, operation))) {
|
|
470
|
+
names.push(/** @type {string} */ (record?.nativeEntries[operation]));
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
providerImportsByModule.set(module.id, names);
|
|
476
|
+
}
|
|
477
|
+
return providerImportsByModule;
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Builds the truthful generated stdlib link metadata for one negotiated closure.
|
|
481
|
+
* Java reports the owner module file as the provider carrier instead of a separate artifact.
|
|
482
|
+
* @param {StdlibProgramLinking | null} linking - Linking plan.
|
|
483
|
+
* @param {Map<string, string>} paths - Planned artifact path by module identity.
|
|
484
|
+
* @param {import("../semantic/types.js").StdlibFacadeProgramDescriptor | undefined} facades - Selected source facade closure.
|
|
485
|
+
* @returns {Record<string, unknown>} Plain JSON metadata.
|
|
486
|
+
*/
|
|
487
|
+
function stdlibLinkMetadata(linking, paths, facades) {
|
|
488
|
+
return {
|
|
489
|
+
...(facades ? { facades } : {}),
|
|
490
|
+
modules: (linking?.negotiation.modules ?? []).map((item) => ({
|
|
491
|
+
identity: item.identity,
|
|
492
|
+
operations: [...item.operations],
|
|
493
|
+
version: item.version
|
|
494
|
+
})),
|
|
495
|
+
providers: (linking?.negotiation.providers ?? []).map((item) => {
|
|
496
|
+
const record = linking?.records.get(item.module);
|
|
497
|
+
const artifactPath = linking?.ownerModuleId !== null && linking?.ownerModuleId !== undefined
|
|
498
|
+
? /** @type {string} */ (paths.get(linking.ownerModuleId))
|
|
499
|
+
: record?.artifact.path;
|
|
500
|
+
return {
|
|
501
|
+
artifact: { mediaType: record?.artifact.mediaType, path: artifactPath },
|
|
502
|
+
dependencies: (record?.dependencies ?? []).map((dependency) => ({ module: dependency.module, range: dependency.range })),
|
|
503
|
+
identity: item.identity,
|
|
504
|
+
module: item.module,
|
|
505
|
+
nativeEntries: { ...item.nativeEntries },
|
|
506
|
+
operations: [...item.operations],
|
|
507
|
+
target: item.target,
|
|
508
|
+
version: item.version
|
|
509
|
+
};
|
|
510
|
+
}),
|
|
511
|
+
schema: "SemantifoldStdlibLink",
|
|
512
|
+
version: 1
|
|
513
|
+
};
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Validates every mandatory semantic location against its owning module source before writer allocation.
|
|
517
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Structurally and semantically validated program.
|
|
518
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
519
|
+
* @returns {void}
|
|
520
|
+
*/
|
|
521
|
+
function validateProgramSourceOwnership(program, language) {
|
|
522
|
+
const sources = new Map(program.sources.map((source) => [source.filename, {
|
|
523
|
+
...source,
|
|
524
|
+
coordinates: createCoordinateIndex(/** @type {string} */ (source.content))
|
|
525
|
+
}]));
|
|
526
|
+
for (const module of program.modules) {
|
|
527
|
+
const source = sources.get(module.sourceFilename);
|
|
528
|
+
if (!source)
|
|
529
|
+
unsupportedCapability(language, "semantic program module source ownership", undefined);
|
|
530
|
+
const fallback = moduleLocation(source.filename, /** @type {string} */ (source.content));
|
|
531
|
+
for (const entry of semanticEntries(module)) {
|
|
532
|
+
const subject = entry.node.kind == "Module" ? "module" : entry.node.kind == "Import" ? "import" :
|
|
533
|
+
entry.node.kind == "Export" ? "export" : "semantic node";
|
|
534
|
+
if (!("location" in entry.node)) {
|
|
535
|
+
if (subject != "semantic node")
|
|
536
|
+
unsupportedCapability(language, `semantic program ${subject} location`, fallback);
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
539
|
+
const location = entry.node.location;
|
|
540
|
+
if (sourceOwnsLocation(source, location))
|
|
541
|
+
continue;
|
|
542
|
+
unsupportedCapability(language, `semantic program ${subject} location source ownership`, fallback);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Checks a normalized UTF-16 location against one exact registered source without throwing.
|
|
548
|
+
* @param {{filename: string, content: string | null, coordinates: ReturnType<typeof createCoordinateIndex>}} source - Owning source.
|
|
549
|
+
* @param {unknown} candidate - Candidate location.
|
|
550
|
+
* @returns {boolean} Whether the source owns the location.
|
|
551
|
+
*/
|
|
552
|
+
function sourceOwnsLocation(source, candidate) {
|
|
553
|
+
if (!isPlainObject(candidate) || candidate.filename != source.filename || !isPlainObject(candidate.start) ||
|
|
554
|
+
!isPlainObject(candidate.end) || !Number.isInteger(candidate.start.offset) || !Number.isInteger(candidate.end.offset) ||
|
|
555
|
+
!Number.isInteger(candidate.start.line) || !Number.isInteger(candidate.start.column) ||
|
|
556
|
+
!Number.isInteger(candidate.end.line) || !Number.isInteger(candidate.end.column))
|
|
557
|
+
return false;
|
|
558
|
+
const startOffset = /** @type {number} */ (candidate.start.offset);
|
|
559
|
+
const endOffset = /** @type {number} */ (candidate.end.offset);
|
|
560
|
+
if (startOffset < 0 || endOffset < startOffset || endOffset > source.coordinates.source.length)
|
|
561
|
+
return false;
|
|
562
|
+
const expectedStart = indexedPointAt(source.coordinates, startOffset);
|
|
563
|
+
const expectedEnd = indexedPointAt(source.coordinates, endOffset);
|
|
564
|
+
return samePoint(candidate.start, expectedStart) && samePoint(candidate.end, expectedEnd);
|
|
565
|
+
}
|
|
566
|
+
/**
|
|
567
|
+
* Compares an untrusted point with one canonical indexed point.
|
|
568
|
+
* @param {Record<string, unknown>} candidate - Candidate point.
|
|
569
|
+
* @param {import("../semantic/types.js").SourcePoint} expected - Canonical point.
|
|
570
|
+
* @returns {boolean} Whether every coordinate agrees.
|
|
571
|
+
*/
|
|
572
|
+
function samePoint(candidate, expected) {
|
|
573
|
+
return candidate.offset == expected.offset && candidate.line == expected.line && candidate.column == expected.column;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Collects nominal failure identities referenced by executable/type nodes outside the module's authority declarations.
|
|
577
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Program module.
|
|
578
|
+
* @returns {Set<string>} Referenced failure declaration identities.
|
|
579
|
+
*/
|
|
580
|
+
function collectReferencedFailureIds(module) {
|
|
581
|
+
/** @type {Set<string>} */
|
|
582
|
+
const ids = new Set();
|
|
583
|
+
const seen = new Set();
|
|
584
|
+
/**
|
|
585
|
+
* Visits one semantic subtree for referenced failures.
|
|
586
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
587
|
+
*/
|
|
588
|
+
const visit = (value) => {
|
|
589
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
590
|
+
return;
|
|
591
|
+
seen.add(value);
|
|
592
|
+
if (!Array.isArray(value)) {
|
|
593
|
+
if (Reflect.get(value, "kind") == "ErrorType" && typeof Reflect.get(value, "declarationId") == "string") {
|
|
594
|
+
ids.add(Reflect.get(value, "declarationId"));
|
|
595
|
+
}
|
|
596
|
+
const failureIds = Reflect.get(value, "failureIds");
|
|
597
|
+
if (Array.isArray(failureIds))
|
|
598
|
+
for (const id of failureIds)
|
|
599
|
+
if (typeof id == "string")
|
|
600
|
+
ids.add(id);
|
|
601
|
+
for (const [key, child] of Object.entries(value)) {
|
|
602
|
+
if (["capabilities", "location", "provenance", "sourceProvenance"].includes(key))
|
|
603
|
+
continue;
|
|
604
|
+
visit(child);
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
else
|
|
608
|
+
for (const child of value)
|
|
609
|
+
visit(child);
|
|
610
|
+
};
|
|
611
|
+
visit({ classes: module.classes, entryPoint: module.entryPoint, functions: module.functions });
|
|
612
|
+
return ids;
|
|
613
|
+
}
|
|
614
|
+
/**
|
|
615
|
+
* Creates and validates every backend-shaped module before any writer is allocated.
|
|
616
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated semantic program.
|
|
617
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
618
|
+
* @param {StdlibProgramLinking | null} [linking] - Planned stdlib provider link.
|
|
619
|
+
* @returns {import("../semantic/types.js").SemanticModule[]} Emission views in dependency order.
|
|
620
|
+
*/
|
|
621
|
+
function prepareEmissionModules(program, language, linking = null) {
|
|
622
|
+
/** @type {Map<string, import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration>} */
|
|
623
|
+
const declarations = new Map();
|
|
624
|
+
for (const module of program.modules) {
|
|
625
|
+
for (const declaration of module.records ?? [])
|
|
626
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
627
|
+
for (const declaration of module.classes ?? [])
|
|
628
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
629
|
+
for (const declaration of module.errors ?? [])
|
|
630
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
631
|
+
for (const declaration of module.functions)
|
|
632
|
+
declarations.set(/** @type {string} */ (declaration.id), declaration);
|
|
633
|
+
}
|
|
634
|
+
const modules = program.modules.map((module) => /** @type {import("../semantic/types.js").SemanticModule} */ ({
|
|
635
|
+
...module,
|
|
636
|
+
entryPoint: module.entryPoint ?? {
|
|
637
|
+
body: { kind: /** @type {const} */ ("Block"), location: module.location, statements: [] },
|
|
638
|
+
kind: /** @type {const} */ ("EntryPoint"),
|
|
639
|
+
location: module.location
|
|
640
|
+
}
|
|
641
|
+
}));
|
|
642
|
+
/** @type {Map<string, Set<string>>} */
|
|
643
|
+
const callEffectsByDeclarationId = new Map();
|
|
644
|
+
for (const module of modules) {
|
|
645
|
+
const programModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ ( /** @type {unknown} */(module));
|
|
646
|
+
const visibleFunctions = new Map();
|
|
647
|
+
const visibleCallEffects = new Map();
|
|
648
|
+
const visibleRecords = new Map();
|
|
649
|
+
const visibleClasses = new Map();
|
|
650
|
+
const visibleErrors = new Map();
|
|
651
|
+
const externalDeclarationIds = new Set();
|
|
652
|
+
const neededFailureIds = collectReferencedFailureIds(programModule);
|
|
653
|
+
const localFailureIds = new Set(programModule.capabilities?.flatMap(({ failures }) => failures.map(({ id }) => id)) ?? []);
|
|
654
|
+
for (const owner of program.modules) {
|
|
655
|
+
if (owner.id == programModule.id)
|
|
656
|
+
continue;
|
|
657
|
+
for (const capability of owner.capabilities ?? []) {
|
|
658
|
+
for (const failure of capability.failures) {
|
|
659
|
+
if (!localFailureIds.has(failure.id) && neededFailureIds.has(failure.id))
|
|
660
|
+
visibleErrors.set(failure.id, failure);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
for (const imported of programModule.imports) {
|
|
665
|
+
const declaration = declarations.get(imported.declarationId);
|
|
666
|
+
if (!declaration)
|
|
667
|
+
unsupportedCapability(language, "program import without a declaration", imported.location);
|
|
668
|
+
externalDeclarationIds.add(imported.declarationId);
|
|
669
|
+
if (imported.symbolKind == "function") {
|
|
670
|
+
visibleFunctions.set(imported.localName, /** @type {import("../semantic/types.js").FunctionDeclaration} */ (declaration));
|
|
671
|
+
visibleCallEffects.set(imported.localName, new Set(callEffectsByDeclarationId.get(imported.declarationId) ?? []));
|
|
672
|
+
}
|
|
673
|
+
else if (imported.symbolKind == "record") {
|
|
674
|
+
visibleRecords.set(imported.declarationId, /** @type {import("../semantic/types.js").RecordDeclaration} */ (declaration));
|
|
675
|
+
}
|
|
676
|
+
else if (imported.symbolKind == "class") {
|
|
677
|
+
visibleClasses.set(imported.declarationId, /** @type {import("../semantic/types.js").ClassDeclaration} */ (declaration));
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
visibleErrors.set(imported.declarationId, /** @type {import("../semantic/types.js").ErrorDeclaration} */ (declaration));
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
if (module.capabilities !== undefined || !linking) {
|
|
684
|
+
preflightEffectCapabilities(module, language, linking ? { usedOperations: (linking.usedOperationsByModule.get(programModule.id) ?? [])
|
|
685
|
+
.map(({ operation }) => operation) } : {});
|
|
686
|
+
}
|
|
687
|
+
validateBackendModule(module, language, {
|
|
688
|
+
externalDeclarationIds,
|
|
689
|
+
program: true,
|
|
690
|
+
visibleCallEffects,
|
|
691
|
+
visibleClasses,
|
|
692
|
+
visibleErrors,
|
|
693
|
+
visibleFunctions,
|
|
694
|
+
visibleRecords
|
|
695
|
+
});
|
|
696
|
+
const localCallEffects = moduleUncheckedErrorEffects(module, { callEffects: visibleCallEffects, functions: visibleFunctions });
|
|
697
|
+
for (const declaration of module.functions) {
|
|
698
|
+
callEffectsByDeclarationId.set(/** @type {string} */ (declaration.id), new Set(localCallEffects.get(declaration.name) ?? []));
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
return modules;
|
|
702
|
+
}
|
|
703
|
+
/**
|
|
704
|
+
* Validates the closed parser-neutral program graph before any target emission.
|
|
705
|
+
* @param {unknown} candidate - Candidate semantic program.
|
|
706
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
707
|
+
* @param {Readonly<Set<import("../semantic/types.js").SemanticLanguage>>} [sourceLanguages] - Accepted source languages.
|
|
708
|
+
* @returns {import("../semantic/types.js").SemanticProgram} Validated program.
|
|
709
|
+
*/
|
|
710
|
+
function validateProgram(candidate, language, sourceLanguages = programTargets) {
|
|
711
|
+
if (!isPlainObject(candidate) || candidate.kind != "Program" || typeof candidate.entryModule != "string" ||
|
|
712
|
+
!isDenseArray(candidate.modules) || candidate.modules.length == 0 || !isDenseArray(candidate.sources) || candidate.sources.length == 0) {
|
|
713
|
+
invalidProgramGeneration("Malformed semantic program.");
|
|
714
|
+
}
|
|
715
|
+
const program = /** @type {import("../semantic/types.js").SemanticProgram} */ (candidate);
|
|
716
|
+
const modules = new Map();
|
|
717
|
+
/** @type {Map<string, {declaration: import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration, module: import("../semantic/types.js").SemanticProgramModule}>} */
|
|
718
|
+
const declarations = new Map();
|
|
719
|
+
/** @type {import("../semantic/types.js").SemanticProgramModule[]} */
|
|
720
|
+
const capabilityModules = [];
|
|
721
|
+
let entryCount = 0;
|
|
722
|
+
const sourceIds = new Set();
|
|
723
|
+
const sourceFilenames = new Set();
|
|
724
|
+
for (const source of program.sources) {
|
|
725
|
+
if (!isPlainObject(source) || typeof source.id != "string" || sourceIds.has(source.id) ||
|
|
726
|
+
typeof source.filename != "string" || !isSafeSourcePath(source.filename) || sourceFilenames.has(source.filename) ||
|
|
727
|
+
typeof source.content != "string" || typeof source.language != "string" || !sourceLanguages.has(source.language)) {
|
|
728
|
+
invalidProgramGeneration("Malformed or duplicate semantic program source registry.");
|
|
729
|
+
}
|
|
730
|
+
sourceIds.add(source.id);
|
|
731
|
+
sourceFilenames.add(source.filename);
|
|
732
|
+
}
|
|
733
|
+
for (const module of program.modules) {
|
|
734
|
+
if (!isPlainObject(module) || module.kind != "Module" || typeof module.id != "string" ||
|
|
735
|
+
!/^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u.test(module.id) || modules.has(module.id) ||
|
|
736
|
+
!isDenseArray(module.functions) || module.records !== undefined && !isDenseArray(module.records) ||
|
|
737
|
+
module.errors !== undefined && !isDenseArray(module.errors) ||
|
|
738
|
+
!isDenseArray(module.imports) || !isDenseArray(module.exports)) {
|
|
739
|
+
unsupportedCapability(language, "malformed or duplicate semantic program module", module?.location);
|
|
740
|
+
}
|
|
741
|
+
if (Reflect.get(module, "classes") !== undefined && (!isDenseArray(module.classes) ||
|
|
742
|
+
Reflect.get(module, "stdlibFacade") === undefined)) {
|
|
743
|
+
unsupportedCapability(language, "Task 033 reference classes are not supported by semantic program generation", Reflect.get(module, "classes")?.[0]?.location ?? module.location);
|
|
744
|
+
}
|
|
745
|
+
if (Reflect.get(module, "capabilities") !== undefined) {
|
|
746
|
+
if (!isDenseArray(module.capabilities) || module.capabilities.length == 0) {
|
|
747
|
+
unsupportedCapability(language, "malformed or empty Task 034 capability graph", module.location);
|
|
748
|
+
}
|
|
749
|
+
capabilityModules.push(module);
|
|
750
|
+
}
|
|
751
|
+
if (typeof module.sourceFilename != "string" || !sourceFilenames.has(module.sourceFilename)) {
|
|
752
|
+
unsupportedCapability(language, "semantic program module source identity", module.location);
|
|
753
|
+
}
|
|
754
|
+
if (module.entryPoint) {
|
|
755
|
+
entryCount++;
|
|
756
|
+
if (module.id != program.entryModule)
|
|
757
|
+
unsupportedCapability(language, "entry point on an unselected module", module.entryPoint.location);
|
|
758
|
+
}
|
|
759
|
+
for (const declaration of [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions]) {
|
|
760
|
+
if (!isPlainObject(declaration) || typeof declaration.id != "string" ||
|
|
761
|
+
!declaration.id.startsWith(`${module.id}#`) || declarations.has(declaration.id)) {
|
|
762
|
+
unsupportedCapability(language, "duplicate or unstable program declaration identity", declaration?.location ?? module.location);
|
|
763
|
+
}
|
|
764
|
+
declarations.set(declaration.id, { declaration, module });
|
|
765
|
+
}
|
|
766
|
+
for (const imported of module.imports) {
|
|
767
|
+
if (!isPlainObject(imported) || imported.kind != "Import" || typeof imported.moduleId != "string" ||
|
|
768
|
+
typeof imported.importedName != "string" || typeof imported.localName != "string" ||
|
|
769
|
+
typeof imported.declarationId != "string" || !["function", "record", "class", "error"].includes(imported.symbolKind) ||
|
|
770
|
+
typeof imported.typeOnly != "boolean") {
|
|
771
|
+
unsupportedCapability(language, "malformed semantic program import", imported?.location ?? module.location);
|
|
772
|
+
}
|
|
773
|
+
}
|
|
774
|
+
for (const exported of module.exports) {
|
|
775
|
+
if (!isPlainObject(exported) || exported.kind != "Export" || typeof exported.exportedName != "string" ||
|
|
776
|
+
typeof exported.declarationId != "string" || !["function", "record", "class", "error"].includes(exported.symbolKind)) {
|
|
777
|
+
unsupportedCapability(language, "malformed semantic program export", exported?.location ?? module.location);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
modules.set(module.id, module);
|
|
781
|
+
}
|
|
782
|
+
if (entryCount != 1 || !modules.get(program.entryModule)?.entryPoint) {
|
|
783
|
+
unsupportedCapability(language, "program without exactly one selected entry point", modules.get(program.entryModule)?.location);
|
|
784
|
+
}
|
|
785
|
+
const selectedModule = /** @type {import("../semantic/types.js").SemanticProgramModule} */ (modules.get(program.entryModule));
|
|
786
|
+
const selectedEntry = selectedModule.entryPoint;
|
|
787
|
+
if (!isPlainObject(selectedEntry?.body) || !isDenseArray(selectedEntry.body.statements) || selectedEntry.body.statements.length == 0) {
|
|
788
|
+
unsupportedCapability(language, "program without a dense non-empty selected entry point block", selectedEntry?.location ?? selectedModule.location);
|
|
789
|
+
}
|
|
790
|
+
const earlier = new Set();
|
|
791
|
+
for (const module of program.modules) {
|
|
792
|
+
const localTargetNames = new Set([...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions]
|
|
793
|
+
.map(({ name }) => targetName(language, name)));
|
|
794
|
+
const importedTargetNames = new Set();
|
|
795
|
+
const localJavaClass = module.records?.[0]?.name ?? module.classes?.[0]?.name ?? module.errors?.[0]?.name ??
|
|
796
|
+
(module.id == program.entryModule ? "Main" : moduleClassName(module.id));
|
|
797
|
+
const javaImportClasses = new Map(language == "java" ? [[localJavaClass, module.id]] : []);
|
|
798
|
+
for (const imported of module.imports) {
|
|
799
|
+
const resolved = declarations.get(imported.declarationId);
|
|
800
|
+
const remoteExport = resolved?.module.exports.find((item) => item.declarationId == imported.declarationId && item.exportedName == imported.importedName);
|
|
801
|
+
if (!resolved || resolved.module.id != imported.moduleId || !earlier.has(imported.moduleId) ||
|
|
802
|
+
!remoteExport) {
|
|
803
|
+
unsupportedCapability(language, "unresolved, private, cyclic, or out-of-order program import", imported.location ?? module.location);
|
|
804
|
+
}
|
|
805
|
+
const declarationKind = resolved.declaration.kind == "FunctionDeclaration" ? "function" :
|
|
806
|
+
resolved.declaration.kind == "RecordDeclaration" ? "record" :
|
|
807
|
+
resolved.declaration.kind == "ClassDeclaration" ? "class" : "error";
|
|
808
|
+
if (imported.symbolKind != remoteExport.symbolKind || imported.symbolKind != declarationKind ||
|
|
809
|
+
imported.typeOnly && declarationKind != "record" && declarationKind != "class") {
|
|
810
|
+
unsupportedCapability(language, "program import declaration kind mismatch", imported.location ?? module.location);
|
|
811
|
+
}
|
|
812
|
+
const importName = programImportName(program, module, imported);
|
|
813
|
+
if (language != "ruby" && language != "java") {
|
|
814
|
+
if (imported.symbolKind != "function")
|
|
815
|
+
validateTargetTypeIdentifier(language, importName, imported.location);
|
|
816
|
+
else
|
|
817
|
+
validateTargetBindingIdentifier(language, importName, "import", imported.location);
|
|
818
|
+
}
|
|
819
|
+
const name = targetName(language, importName);
|
|
820
|
+
if (language != "ruby" && language != "java" && (localTargetNames.has(name) || importedTargetNames.has(name))) {
|
|
821
|
+
unsupportedCapability(language, `target import-name collision '${importName}'`, imported.location);
|
|
822
|
+
}
|
|
823
|
+
if (language == "java") {
|
|
824
|
+
const importedClass = imported.symbolKind == "function" ? moduleClassName(resolved.module.id) : resolved.declaration.name;
|
|
825
|
+
const existingOwner = javaImportClasses.get(importedClass);
|
|
826
|
+
if (existingOwner && existingOwner != resolved.module.id) {
|
|
827
|
+
unsupportedCapability(language, `target import-class collision '${importedClass}'`, imported.location);
|
|
828
|
+
}
|
|
829
|
+
javaImportClasses.set(importedClass, resolved.module.id);
|
|
830
|
+
}
|
|
831
|
+
if (language == "ruby") {
|
|
832
|
+
const importedModule = moduleClassName(resolved.module.id);
|
|
833
|
+
if (localTargetNames.has(importedModule)) {
|
|
834
|
+
unsupportedCapability(language, `target import-module collision '${importedModule}'`, imported.location);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
importedTargetNames.add(name);
|
|
838
|
+
}
|
|
839
|
+
const valueDeclarationIds = new Set(module.imports.filter(({ typeOnly }) => !typeOnly).map(({ declarationId }) => declarationId));
|
|
840
|
+
const typeOnlyDeclarationIds = new Set(module.imports
|
|
841
|
+
.filter(({ declarationId, typeOnly }) => typeOnly && !valueDeclarationIds.has(declarationId))
|
|
842
|
+
.map(({ declarationId }) => declarationId));
|
|
843
|
+
const valueConstruction = findTypeOnlyValueConstruction(module, typeOnlyDeclarationIds);
|
|
844
|
+
if (valueConstruction) {
|
|
845
|
+
unsupportedCapability(language, "type-only program import used as a value", valueConstruction.location ?? module.location);
|
|
846
|
+
}
|
|
847
|
+
const exportNames = new Set();
|
|
848
|
+
for (const exported of module.exports) {
|
|
849
|
+
const resolved = declarations.get(exported.declarationId);
|
|
850
|
+
const name = targetName(language, exported.exportedName);
|
|
851
|
+
if (language == "javascript" || language == "typescript") {
|
|
852
|
+
validateTargetIdentifier(language, exported.exportedName, "export", exported.location ?? module.location);
|
|
853
|
+
}
|
|
854
|
+
if (!resolved || resolved.module.id != module.id || exportNames.has(name)) {
|
|
855
|
+
unsupportedCapability(language, `unresolved or colliding target export '${exported.exportedName}'`, exported.location ?? module.location);
|
|
856
|
+
}
|
|
857
|
+
const declarationKind = resolved.declaration.kind == "FunctionDeclaration" ? "function" :
|
|
858
|
+
resolved.declaration.kind == "RecordDeclaration" ? "record" :
|
|
859
|
+
resolved.declaration.kind == "ClassDeclaration" ? "class" : "error";
|
|
860
|
+
if (exported.symbolKind != declarationKind) {
|
|
861
|
+
unsupportedCapability(language, "program export declaration kind mismatch", exported.location ?? module.location);
|
|
862
|
+
}
|
|
863
|
+
if (language != "javascript" && language != "typescript" && exported.exportedName != resolved.declaration.name) {
|
|
864
|
+
unsupportedCapability(language, `export alias '${exported.exportedName}' without an equivalent target binding`, exported.location ?? resolved.declaration.location);
|
|
865
|
+
}
|
|
866
|
+
exportNames.add(name);
|
|
867
|
+
}
|
|
868
|
+
if (language == "php") {
|
|
869
|
+
const exportedDeclarationIds = new Set(module.exports.map(({ declarationId }) => declarationId));
|
|
870
|
+
const privateDeclaration = [...module.records ?? [], ...module.classes ?? [], ...module.errors ?? [], ...module.functions].find(({ id }) => typeof id == "string" && !exportedDeclarationIds.has(id));
|
|
871
|
+
if (privateDeclaration) {
|
|
872
|
+
unsupportedCapability(language, `non-exported declaration '${privateDeclaration.name}' without target-private module visibility`, privateDeclaration.location);
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
earlier.add(module.id);
|
|
876
|
+
}
|
|
877
|
+
validateProgramStdlibContract(program, language, capabilityModules);
|
|
878
|
+
validateProgramStdlibFacades(program, language);
|
|
879
|
+
return program;
|
|
880
|
+
}
|
|
881
|
+
/**
|
|
882
|
+
* Validates compiler-selected facade descriptors, executable sources, module markers, and native identity evidence.
|
|
883
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Candidate program.
|
|
884
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language for diagnostics.
|
|
885
|
+
* @returns {void}
|
|
886
|
+
*/
|
|
887
|
+
function validateProgramStdlibFacades(program, language) {
|
|
888
|
+
const descriptor = Reflect.get(program, "stdlibFacades");
|
|
889
|
+
const markedModules = program.modules.filter((module) => Reflect.get(module, "stdlibFacade") !== undefined);
|
|
890
|
+
const facadeSources = program.sources.filter((source) => Reflect.get(source, "ownership") == "facade");
|
|
891
|
+
const evidencedImports = program.modules.flatMap((module) => module.imports.filter((item) => Reflect.get(item, "stdlibFacade") !== undefined));
|
|
892
|
+
if (descriptor === undefined) {
|
|
893
|
+
if (markedModules.length > 0 || facadeSources.length > 0 || evidencedImports.length > 0) {
|
|
894
|
+
invalidFacadeDescriptor(language, "Facade modules, sources, or import evidence require a complete program facade descriptor.");
|
|
895
|
+
}
|
|
896
|
+
return;
|
|
897
|
+
}
|
|
898
|
+
if (!isPlainObject(descriptor) || descriptor.schema != "SemantifoldStdlibFacades" || descriptor.version != 1 ||
|
|
899
|
+
typeof descriptor.language != "string" || !programTargets.has(descriptor.language) || !isDenseArray(descriptor.modules) ||
|
|
900
|
+
descriptor.modules.length == 0) {
|
|
901
|
+
invalidFacadeDescriptor(language, "The program facade descriptor is malformed.");
|
|
902
|
+
}
|
|
903
|
+
const facadeLanguage = /** @type {import("../semantic/types.js").SemanticLanguage} */ (descriptor.language);
|
|
904
|
+
const records = descriptor.modules.map((item) => {
|
|
905
|
+
if (!isPlainObject(item) || typeof item.identity != "string" || typeof item.version != "string") {
|
|
906
|
+
invalidFacadeDescriptor(language, "The program facade module descriptor is malformed.");
|
|
907
|
+
}
|
|
908
|
+
return stdlibFacadeRegistry.resolveIdentity(item.identity, facadeLanguage, item.version);
|
|
909
|
+
});
|
|
910
|
+
const expected = stdlibFacadeProgramDescriptor(facadeLanguage, records);
|
|
911
|
+
if (!equalPlainData(descriptor, expected)) {
|
|
912
|
+
invalidFacadeDescriptor(language, "The program facade descriptor does not match the registered versioned facade closure.");
|
|
913
|
+
}
|
|
914
|
+
const selectedRecords = new Map();
|
|
915
|
+
for (const record of records) {
|
|
916
|
+
if (selectedRecords.has(record.identity)) {
|
|
917
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' is selected more than once.`);
|
|
918
|
+
}
|
|
919
|
+
for (const dependency of record.dependencies) {
|
|
920
|
+
const resolved = stdlibFacadeRegistry.resolveIdentity(dependency.identity, facadeLanguage, dependency.range);
|
|
921
|
+
const selected = selectedRecords.get(resolved.identity);
|
|
922
|
+
if (!selected || selected.version != resolved.version) {
|
|
923
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' dependency '${resolved.identity}@${resolved.version}' is missing or out of order.`);
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
selectedRecords.set(record.identity, record);
|
|
927
|
+
}
|
|
928
|
+
if (markedModules.length != records.length) {
|
|
929
|
+
invalidFacadeDescriptor(language, "The program facade descriptor does not match its executable semantic modules.");
|
|
930
|
+
}
|
|
931
|
+
if (program.sources.some((source) => source.language != facadeLanguage ||
|
|
932
|
+
!["application", "facade"].includes(String(Reflect.get(source, "ownership"))))) {
|
|
933
|
+
invalidFacadeDescriptor(language, "Facade programs require one source language and explicit application/facade ownership.");
|
|
934
|
+
}
|
|
935
|
+
const selectedIdentities = new Set(records.map(({ identity }) => identity));
|
|
936
|
+
const registeredModules = reparseRegisteredFacadeModules(program, facadeLanguage, language);
|
|
937
|
+
for (let index = 0; index < records.length; index += 1) {
|
|
938
|
+
const record = records[index];
|
|
939
|
+
const module = markedModules[index];
|
|
940
|
+
const marker = Reflect.get(module, "stdlibFacade");
|
|
941
|
+
if (!isPlainObject(marker) || Object.keys(marker).sort().join(",") != "identity,version" ||
|
|
942
|
+
marker.identity != record.identity || marker.version != record.version || module.id != record.source.id ||
|
|
943
|
+
module.sourceFilename != record.source.filename) {
|
|
944
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' semantic module identity is not canonical.`);
|
|
945
|
+
}
|
|
946
|
+
const source = program.sources.find(({ filename }) => filename == record.source.filename);
|
|
947
|
+
if (!source || source.content != record.source.content || Reflect.get(source, "ownership") != "facade") {
|
|
948
|
+
invalidFacadeDescriptor(language, `Facade '${record.identity}' executable source does not match its registered definition.`);
|
|
949
|
+
}
|
|
950
|
+
const registeredModule = registeredModules.get(record.identity);
|
|
951
|
+
if (!registeredModule || !equalPlainData(module, registeredModule)) {
|
|
952
|
+
invalidFacadeAuthority(language, `Facade '${record.identity}' semantic module does not match its registered executable source.`, module.location);
|
|
953
|
+
}
|
|
954
|
+
const allowedOperations = new Set(record.requirements.flatMap(({ operations }) => operations));
|
|
955
|
+
const usedOperations = collectDeclaredEffectOperations(module);
|
|
956
|
+
if (allowedOperations.size != usedOperations.size || [...allowedOperations].some((operation) => !usedOperations.has(operation))) {
|
|
957
|
+
invalidFacadeAuthority(language, `Facade '${record.identity}' semantic body does not match its declared canonical requirements.`, module.location);
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
if (facadeSources.length != records.length) {
|
|
961
|
+
invalidFacadeDescriptor(language, "The program contains an unselected compiler-owned facade source.");
|
|
962
|
+
}
|
|
963
|
+
if (evidencedImports.length == 0) {
|
|
964
|
+
invalidFacadeDescriptor(language, "The selected facade closure has no parser-proved native import evidence.");
|
|
965
|
+
}
|
|
966
|
+
for (const imported of evidencedImports) {
|
|
967
|
+
const evidence = Reflect.get(imported, "stdlibFacade");
|
|
968
|
+
if (!isPlainObject(evidence) || Object.keys(evidence).sort().join(",") !=
|
|
969
|
+
"facadeIdentity,facadeVersion,nativeModule,nativeSymbol,schema,version" ||
|
|
970
|
+
evidence.schema != "SemantifoldStdlibFacadeResolution" || evidence.version != 1 ||
|
|
971
|
+
typeof evidence.facadeIdentity != "string" || typeof evidence.facadeVersion != "string" ||
|
|
972
|
+
typeof evidence.nativeModule != "string" || typeof evidence.nativeSymbol != "string") {
|
|
973
|
+
invalidFacadeDescriptor(language, "A facade import has malformed native identity evidence.");
|
|
974
|
+
}
|
|
975
|
+
const record = stdlibFacadeRegistry.resolveFacade(facadeLanguage, evidence.nativeModule, evidence.nativeSymbol, evidence.facadeVersion);
|
|
976
|
+
if (record.identity != evidence.facadeIdentity || !selectedIdentities.has(record.identity) || imported.moduleId != record.source.id ||
|
|
977
|
+
imported.importedName != evidence.nativeSymbol) {
|
|
978
|
+
invalidFacadeDescriptor(language, "A facade import does not match its registered native module and symbol identity.");
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
/**
|
|
983
|
+
* Collects every canonical operation present in one validated facade implementation.
|
|
984
|
+
* This checks the facade's complete declared authority independently from program reachability.
|
|
985
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Facade module.
|
|
986
|
+
* @returns {Set<string>} Used operation names.
|
|
987
|
+
*/
|
|
988
|
+
function collectDeclaredEffectOperations(module) {
|
|
989
|
+
const operationNames = new Map(module.capabilities?.flatMap(({ operations }) => operations.map((operation) => [operation.id, operation.name])) ?? []);
|
|
990
|
+
const used = new Set();
|
|
991
|
+
const seen = new Set();
|
|
992
|
+
/**
|
|
993
|
+
* Visits one facade semantic subtree.
|
|
994
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
995
|
+
*/
|
|
996
|
+
const visit = (value) => {
|
|
997
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
998
|
+
return;
|
|
999
|
+
seen.add(value);
|
|
1000
|
+
if (!Array.isArray(value)) {
|
|
1001
|
+
const operation = Reflect.get(value, "kind") == "EffectCallExpression" ? Reflect.get(value, "operation") : undefined;
|
|
1002
|
+
if (typeof operation == "string" && operationNames.has(operation))
|
|
1003
|
+
used.add(/** @type {string} */ (operationNames.get(operation)));
|
|
1004
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1005
|
+
if (["capabilities", "location", "provenance", "resolution", "sourceProvenance"].includes(key))
|
|
1006
|
+
continue;
|
|
1007
|
+
visit(child);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
else
|
|
1011
|
+
for (const child of value)
|
|
1012
|
+
visit(child);
|
|
1013
|
+
};
|
|
1014
|
+
visit({ classes: module.classes, entryPoint: module.entryPoint, functions: module.functions });
|
|
1015
|
+
return used;
|
|
1016
|
+
}
|
|
1017
|
+
/**
|
|
1018
|
+
* Recompiles the registry-selected facade closure from retained caller inputs and registered facade source.
|
|
1019
|
+
* This parser-backed reference graph is created during validation, before provider planning or writer allocation.
|
|
1020
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Untrusted mutable semantic program.
|
|
1021
|
+
* @param {import("../semantic/types.js").SemanticLanguage} facadeLanguage - Selected source-language facade profile.
|
|
1022
|
+
* @param {import("../semantic/types.js").SemanticLanguage} diagnosticLanguage - Target language for boundary diagnostics.
|
|
1023
|
+
* @returns {Map<string, import("../semantic/types.js").SemanticProgramModule>} Canonical semantic modules by facade identity.
|
|
1024
|
+
*/
|
|
1025
|
+
function reparseRegisteredFacadeModules(program, facadeLanguage, diagnosticLanguage) {
|
|
1026
|
+
const applicationModules = program.modules.filter((module) => Reflect.get(module, "stdlibFacade") === undefined);
|
|
1027
|
+
const modulesByFilename = new Map(applicationModules.map((module) => [module.sourceFilename, module]));
|
|
1028
|
+
const applicationSources = program.sources.filter((source) => Reflect.get(source, "ownership") == "application").map((source) => {
|
|
1029
|
+
const module = modulesByFilename.get(source.filename);
|
|
1030
|
+
if (!module)
|
|
1031
|
+
invalidFacadeDescriptor(diagnosticLanguage, `Application source '${source.filename}' has no matching semantic module for facade verification.`);
|
|
1032
|
+
return {
|
|
1033
|
+
filename: source.filename,
|
|
1034
|
+
id: /** @type {import("../semantic/types.js").SemanticProgramModule} */ (module).id,
|
|
1035
|
+
language: facadeLanguage,
|
|
1036
|
+
source: /** @type {string} */ (source.content)
|
|
1037
|
+
};
|
|
1038
|
+
});
|
|
1039
|
+
if (applicationSources.length != applicationModules.length) {
|
|
1040
|
+
invalidFacadeDescriptor(diagnosticLanguage, "Facade verification requires one retained application source per semantic module.");
|
|
1041
|
+
}
|
|
1042
|
+
const reparsed = parseProgramSource({ entryModule: program.entryModule, sources: applicationSources });
|
|
1043
|
+
const modules = new Map();
|
|
1044
|
+
for (const module of reparsed.modules) {
|
|
1045
|
+
if (!module.stdlibFacade)
|
|
1046
|
+
continue;
|
|
1047
|
+
if (modules.has(module.stdlibFacade.identity)) {
|
|
1048
|
+
invalidFacadeDescriptor(diagnosticLanguage, `Registered facade '${module.stdlibFacade.identity}' reparsed more than once.`);
|
|
1049
|
+
}
|
|
1050
|
+
modules.set(module.stdlibFacade.identity, module);
|
|
1051
|
+
}
|
|
1052
|
+
return modules;
|
|
1053
|
+
}
|
|
1054
|
+
/**
|
|
1055
|
+
* Compares closed plain JSON-shaped data without coercion or key-order assumptions.
|
|
1056
|
+
* @param {unknown} left - Candidate value.
|
|
1057
|
+
* @param {unknown} right - Expected value.
|
|
1058
|
+
* @returns {boolean} Exact recursive equivalence.
|
|
1059
|
+
*/
|
|
1060
|
+
function equalPlainData(left, right) {
|
|
1061
|
+
if (left === right)
|
|
1062
|
+
return true;
|
|
1063
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
1064
|
+
return Array.isArray(left) && Array.isArray(right) && isDenseArray(left) && isDenseArray(right) &&
|
|
1065
|
+
left.length == right.length && left.every((value, index) => equalPlainData(value, right[index]));
|
|
1066
|
+
}
|
|
1067
|
+
if (!isPlainObject(left) || !isPlainObject(right))
|
|
1068
|
+
return false;
|
|
1069
|
+
const leftKeys = Object.keys(left).sort();
|
|
1070
|
+
const rightKeys = Object.keys(right).sort();
|
|
1071
|
+
return leftKeys.length == rightKeys.length && leftKeys.every((key, index) => key == rightKeys[index] && equalPlainData(left[key], right[key]));
|
|
1072
|
+
}
|
|
1073
|
+
/**
|
|
1074
|
+
* Throws one stable facade artifact-boundary diagnostic.
|
|
1075
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1076
|
+
* @param {string} message - Diagnostic detail.
|
|
1077
|
+
* @returns {never} Always throws.
|
|
1078
|
+
*/
|
|
1079
|
+
function invalidFacadeDescriptor(language, message) {
|
|
1080
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_FACADE_DESCRIPTOR_INVALID", language, message });
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Throws when a facade semantic body exceeds or omits its registry-declared authority.
|
|
1084
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1085
|
+
* @param {string} message - Diagnostic detail.
|
|
1086
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Facade source location.
|
|
1087
|
+
* @returns {never} Always throws.
|
|
1088
|
+
*/
|
|
1089
|
+
function invalidFacadeAuthority(language, message, location) {
|
|
1090
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_FACADE_AUTHORITY_FORGED", language, location, message });
|
|
1091
|
+
}
|
|
1092
|
+
/**
|
|
1093
|
+
* Validates the program stdlib link descriptor against its capability modules.
|
|
1094
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Candidate program.
|
|
1095
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1096
|
+
* @param {import("../semantic/types.js").SemanticProgramModule[]} capabilityModules - Modules carrying capabilities.
|
|
1097
|
+
* @returns {void}
|
|
1098
|
+
*/
|
|
1099
|
+
function validateProgramStdlibContract(program, language, capabilityModules) {
|
|
1100
|
+
const contract = Reflect.get(program, "stdlibContract");
|
|
1101
|
+
const contracts = Reflect.get(program, "stdlibContracts");
|
|
1102
|
+
if (capabilityModules.length == 0) {
|
|
1103
|
+
if (contract !== undefined || contracts !== undefined) {
|
|
1104
|
+
throw new SemantifoldDiagnostic({
|
|
1105
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1106
|
+
language,
|
|
1107
|
+
message: "A declared standard-library contract requires capability modules."
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
if (contract !== undefined && contracts !== undefined) {
|
|
1113
|
+
throw new SemantifoldDiagnostic({
|
|
1114
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1115
|
+
language,
|
|
1116
|
+
message: "A program cannot declare both singular and plural standard-library contract descriptors."
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
if (contract === undefined && contracts === undefined) {
|
|
1120
|
+
unsupportedCapability(language, "program modules with capabilities require a declared standard-library contract", capabilityModules[0].location);
|
|
1121
|
+
}
|
|
1122
|
+
const declared = contracts === undefined ? [contract] : contracts;
|
|
1123
|
+
if (!isDenseArray(declared) || declared.length == 0) {
|
|
1124
|
+
throw new SemantifoldDiagnostic({
|
|
1125
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1126
|
+
language,
|
|
1127
|
+
message: "The declared standard-library contract descriptor list is malformed or empty."
|
|
1128
|
+
});
|
|
1129
|
+
}
|
|
1130
|
+
const identities = new Set();
|
|
1131
|
+
for (const descriptor of declared) {
|
|
1132
|
+
if (!isPlainObject(descriptor) || Object.keys(descriptor).some((key) => key != "identity" && key != "contractVersion")) {
|
|
1133
|
+
throw new SemantifoldDiagnostic({
|
|
1134
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1135
|
+
language,
|
|
1136
|
+
message: "The declared standard-library contract descriptor is malformed."
|
|
1137
|
+
});
|
|
1138
|
+
}
|
|
1139
|
+
const identity = descriptor.identity;
|
|
1140
|
+
if (typeof identity != "string" || identity.length == 0 || identities.has(identity) ||
|
|
1141
|
+
!listStdlibModules().some(({ identity: registered }) => registered == identity)) {
|
|
1142
|
+
throw new SemantifoldDiagnostic({
|
|
1143
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1144
|
+
language,
|
|
1145
|
+
message: `Declared standard-library contract '${String(identity)}' is duplicate or not a registered canonical module.`
|
|
1146
|
+
});
|
|
1147
|
+
}
|
|
1148
|
+
if (descriptor.contractVersion !== undefined && parseStdlibVersionRange(descriptor.contractVersion) === null) {
|
|
1149
|
+
throw new SemantifoldDiagnostic({
|
|
1150
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1151
|
+
language,
|
|
1152
|
+
message: `Declared standard-library contract version '${String(descriptor.contractVersion)}' is not canonical.`
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
identities.add(identity);
|
|
1156
|
+
}
|
|
1157
|
+
for (const module of capabilityModules) {
|
|
1158
|
+
for (const capability of module.capabilities ?? []) {
|
|
1159
|
+
if (!isPlainObject(capability) || typeof capability.authorityId != "string" || !identities.has(capability.authorityId)) {
|
|
1160
|
+
throw new SemantifoldDiagnostic({
|
|
1161
|
+
code: "STDLIB_LINK_FAILURE",
|
|
1162
|
+
language,
|
|
1163
|
+
message: `Capability authority '${String(Reflect.get(capability, "authorityId"))}' does not match a declared standard-library contract.`
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
}
|
|
1168
|
+
}
|
|
1169
|
+
/**
|
|
1170
|
+
* Finds a record construction that crosses a type-only import edge.
|
|
1171
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Importing semantic module.
|
|
1172
|
+
* @param {Set<string>} typeOnlyDeclarationIds - Imported identities unavailable in value positions.
|
|
1173
|
+
* @returns {import("../semantic/types.js").RecordConstruction | undefined} Invalid construction when present.
|
|
1174
|
+
*/
|
|
1175
|
+
function findTypeOnlyValueConstruction(module, typeOnlyDeclarationIds) {
|
|
1176
|
+
if (typeOnlyDeclarationIds.size == 0)
|
|
1177
|
+
return undefined;
|
|
1178
|
+
const seen = new WeakSet();
|
|
1179
|
+
/**
|
|
1180
|
+
* Visits one semantic value.
|
|
1181
|
+
* @param {unknown} value - Candidate semantic subtree.
|
|
1182
|
+
* @returns {import("../semantic/types.js").RecordConstruction | undefined} Invalid construction when present.
|
|
1183
|
+
*/
|
|
1184
|
+
function visit(value) {
|
|
1185
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
1186
|
+
return undefined;
|
|
1187
|
+
seen.add(value);
|
|
1188
|
+
const object = /** @type {Record<string, unknown>} */ (value);
|
|
1189
|
+
if (object.kind == "RecordConstruction" && isPlainObject(object.record) &&
|
|
1190
|
+
typeof object.record.declarationId == "string" && typeOnlyDeclarationIds.has(object.record.declarationId)) {
|
|
1191
|
+
return /** @type {import("../semantic/types.js").RecordConstruction} */ (value);
|
|
1192
|
+
}
|
|
1193
|
+
for (const child of Object.values(object)) {
|
|
1194
|
+
const found = visit(child);
|
|
1195
|
+
if (found)
|
|
1196
|
+
return found;
|
|
1197
|
+
}
|
|
1198
|
+
return undefined;
|
|
1199
|
+
}
|
|
1200
|
+
return visit({ entryPoint: module.entryPoint, functions: module.functions });
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Plans all paths before emission and rejects exact/case/file-directory collisions.
|
|
1204
|
+
* @param {import("../semantic/types.js").SemanticProgram} program - Validated program.
|
|
1205
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target language.
|
|
1206
|
+
* @param {StdlibProgramLinking | null} [linking] - Planned stdlib provider link.
|
|
1207
|
+
* @returns {Map<string, string>} Path by module identity.
|
|
1208
|
+
*/
|
|
1209
|
+
function planModulePaths(program, language, linking = null) {
|
|
1210
|
+
const extension = language == "javascript" ? ".js" : language == "typescript" ? ".ts" : language == "ruby" ? ".rb" :
|
|
1211
|
+
language == "php" ? ".php" : ".java";
|
|
1212
|
+
const paths = new Map();
|
|
1213
|
+
const folded = new Set();
|
|
1214
|
+
const targetModuleNames = new Set();
|
|
1215
|
+
const providerPaths = linking ? linking.negotiation.providers.map(({ module }) =>
|
|
1216
|
+
/** @type {import("../stdlib-providers.js").StdlibProviderRecord} */ (linking.records.get(module)).artifact.path) : [];
|
|
1217
|
+
const foldedProviders = new Map();
|
|
1218
|
+
for (const providerPath of providerPaths) {
|
|
1219
|
+
const key = providerPath.toLocaleLowerCase("en-US");
|
|
1220
|
+
if (!isSafeArtifactPath(providerPath) || folded.has(key)) {
|
|
1221
|
+
throw new SemantifoldDiagnostic({ code: "STDLIB_NAME_COLLISION", language,
|
|
1222
|
+
message: `Stdlib provider artifact path '${providerPath}' is unsafe or colliding.` });
|
|
1223
|
+
}
|
|
1224
|
+
folded.add(key);
|
|
1225
|
+
foldedProviders.set(providerPath.toLocaleLowerCase("en-US").replaceAll(".", "/"), providerPath);
|
|
1226
|
+
}
|
|
1227
|
+
for (const module of program.modules) {
|
|
1228
|
+
let path = `${module.id.replaceAll(".", "/")}${extension}`;
|
|
1229
|
+
const providerPath = foldedProviders.get(path.toLocaleLowerCase("en-US").replaceAll(".", "/"));
|
|
1230
|
+
if (providerPath !== undefined) {
|
|
1231
|
+
throw new SemantifoldDiagnostic({
|
|
1232
|
+
code: "STDLIB_NAME_COLLISION",
|
|
1233
|
+
language,
|
|
1234
|
+
message: `Module path '${path}' collides with the stdlib provider artifact '${providerPath}'.`
|
|
1235
|
+
});
|
|
1236
|
+
}
|
|
1237
|
+
const targetModuleName = moduleClassName(module.id);
|
|
1238
|
+
if (language == "php" || language == "ruby") {
|
|
1239
|
+
const key = language == "php" ? targetModuleName.toLocaleLowerCase("en-US") : targetModuleName;
|
|
1240
|
+
if (targetModuleNames.has(key)) {
|
|
1241
|
+
unsupportedCapability(language, `target module-name collision '${targetModuleName}'`, module.location);
|
|
1242
|
+
}
|
|
1243
|
+
targetModuleNames.add(key);
|
|
1244
|
+
}
|
|
1245
|
+
if (language == "php") {
|
|
1246
|
+
validateTargetIdentifier(language, targetModuleName, "module", module.location);
|
|
1247
|
+
validateTargetTypeIdentifier(language, targetModuleName, module.location);
|
|
1248
|
+
}
|
|
1249
|
+
if (language == "ruby")
|
|
1250
|
+
validateTargetTypeIdentifier(language, targetModuleName, module.location);
|
|
1251
|
+
if (language == "java") {
|
|
1252
|
+
for (const segment of module.id.split("."))
|
|
1253
|
+
validateTargetIdentifier(language, segment, "module", module.location);
|
|
1254
|
+
const nominalCount = (module.records?.length ?? 0) + (module.classes?.length ?? 0) + (module.errors?.length ?? 0);
|
|
1255
|
+
if (module.id.includes("-") || nominalCount > 1 ||
|
|
1256
|
+
nominalCount > 0 && (module.functions.length > 0 || module.entryPoint)) {
|
|
1257
|
+
unsupportedCapability(language, "Java module layout requiring multiple public declarations in one semantic module", module.location);
|
|
1258
|
+
}
|
|
1259
|
+
const className = module.records?.[0]?.name ?? module.classes?.[0]?.name ?? module.errors?.[0]?.name ??
|
|
1260
|
+
(module.id == program.entryModule ? "Main" : targetModuleName);
|
|
1261
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/u.test(className)) {
|
|
1262
|
+
unsupportedCapability(language, `invalid Java public class name '${className}'`, module.location);
|
|
1263
|
+
}
|
|
1264
|
+
if (module.id != program.entryModule)
|
|
1265
|
+
validateTargetTypeIdentifier(language, className, module.location);
|
|
1266
|
+
path = `semantifold/generated/${module.id.replaceAll(".", "/")}/${className}.java`;
|
|
1267
|
+
}
|
|
1268
|
+
const key = path.toLocaleLowerCase("en-US");
|
|
1269
|
+
if (!isSafeArtifactPath(path) || folded.has(key))
|
|
1270
|
+
unsupportedCapability(language, `unsafe or colliding target path '${path}'`, module.location);
|
|
1271
|
+
folded.add(key);
|
|
1272
|
+
paths.set(module.id, path);
|
|
1273
|
+
}
|
|
1274
|
+
return paths;
|
|
1275
|
+
}
|
|
1276
|
+
/**
|
|
1277
|
+
* Converts a logical module identity to its canonical target type segment.
|
|
1278
|
+
* @param {string} id - Logical module identity.
|
|
1279
|
+
* @returns {string} Target class name.
|
|
1280
|
+
*/
|
|
1281
|
+
function moduleClassName(id) {
|
|
1282
|
+
return id.split(/[._-]+/u).map((part) => `${part[0].toUpperCase()}${part.slice(1)}`).join("");
|
|
1283
|
+
}
|
|
1284
|
+
/**
|
|
1285
|
+
* Normalizes a declaration or binding name for target collision checks.
|
|
1286
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Target.
|
|
1287
|
+
* @param {string} name - Name.
|
|
1288
|
+
* @returns {string} Collision key.
|
|
1289
|
+
*/
|
|
1290
|
+
function targetName(language, name) {
|
|
1291
|
+
return language == "php" ? name.toLocaleLowerCase("en-US") : name;
|
|
1292
|
+
}
|
|
1293
|
+
/**
|
|
1294
|
+
* Reports whether a candidate is a direct plain object.
|
|
1295
|
+
* @param {unknown} value - Candidate.
|
|
1296
|
+
* @returns {value is Record<string, unknown>} Whether the value is a plain object.
|
|
1297
|
+
*/
|
|
1298
|
+
function isPlainObject(value) {
|
|
1299
|
+
return Boolean(value) && typeof value == "object" && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype;
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Raises a stable malformed program-generation request diagnostic.
|
|
1303
|
+
* @param {string} message - Stable failure.
|
|
1304
|
+
* @returns {never} Always throws.
|
|
1305
|
+
*/
|
|
1306
|
+
function invalidProgramGeneration(message) {
|
|
1307
|
+
throw new SemantifoldDiagnostic({ code: "INVALID_PROGRAM", language: "program", message });
|
|
1308
|
+
}
|
|
1309
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3JhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9iYWNrZW5kcy9wcm9ncmFtLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sYUFBYSxDQUFBO0FBQ3hDLE9BQU8sRUFBQyxrQkFBa0IsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFBO0FBQ3hFLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBQzFELE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxxQkFBcUIsRUFBRSxlQUFlLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUM5RixPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUN4RCxPQUFPLEVBQUMsZUFBZSxFQUFFLGFBQWEsRUFBQyxNQUFNLGVBQWUsQ0FBQTtBQUM1RCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsY0FBYyxFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzdGLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUN6RCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsdUJBQXVCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQTtBQUNoRixPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUNuRSxPQUFPLEVBQUMsd0JBQXdCLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUNqRSxPQUFPLEVBQUMsNkJBQTZCLEVBQUUsb0JBQW9CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQTtBQUN4RixPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUM3RCxPQUFPLEVBQUMsMkJBQTJCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDeEQsT0FBTyxFQUFDLCtCQUEr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QUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUE7QUFDL0YsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxVQUFVLENBQUMsUUFBUSxFQUFFLElBQUk7SUFDaEMsT0FBTyxRQUFRLElBQUksS0FBSyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQTtBQUNuRSxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsYUFBYSxDQUFDLEtBQUs7SUFDMUIsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksT0FBTyxLQUFLLElBQUksUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUE7QUFDaEksQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLHdCQUF3QixDQUFDLE9BQU87SUFDdkMsTUFBTSxJQUFJLHFCQUFxQixDQUFDLEVBQUMsSUFBSSxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQTtBQUMxRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7aXNEZW5zZUFycmF5fSBmcm9tIFwiLi4vYXJyYXkuanNcIlxuaW1wb3J0IHtpc1NhZmVBcnRpZmFjdFBhdGgsIGlzU2FmZVNvdXJjZVBhdGh9IGZyb20gXCIuLi9hcnRpZmFjdC1wYXRoLmpzXCJcbmltcG9ydCB7Y3JlYXRlR2VuZXJhdGVkQXJ0aWZhY3RTZXR9IGZyb20gXCIuLi9hcnRpZmFjdHMuanNcIlxuaW1wb3J0IHtTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eSwgdW5zdXBwb3J0ZWRSb2xlfSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge3BhcnNlUHJvZ3JhbVNvdXJjZX0gZnJvbSBcIi4uL2Zyb250ZW5kcy9wcm9ncmFtLmpzXCJcbmltcG9ydCB7bGFuZ3VhZ2VSZWdpc3RyeX0gZnJvbSBcIi4uL2xhbmd1YWdlLXJlZ2lzdHJ5LmpzXCJcbmltcG9ydCB7ZmluYWxpemVNYXBwaW5nLCB0b1NvdXJjZU1hcFYzfSBmcm9tIFwiLi4vbWFwcGluZy5qc1wiXG5pbXBvcnQge2NyZWF0ZUNvb3JkaW5hdGVJbmRleCwgaW5kZXhlZFBvaW50QXQsIG1vZHVsZUxvY2F0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvbG9jYXRpb24uanNcIlxuaW1wb3J0IHtzZW1hbnRpY0VudHJpZXN9IGZyb20gXCIuLi9zZW1hbnRpYy9wcm92ZW5hbmNlLmpzXCJcbmltcG9ydCB7bGlzdFN0ZGxpYk1vZHVsZXMsIHBhcnNlU3RkbGliVmVyc2lvblJhbmdlfSBmcm9tIFwiLi4vc2VtYW50aWMvc3RkbGliLmpzXCJcbmltcG9ydCB7bW9kdWxlVW5jaGVja2VkRXJyb3JFZmZlY3RzfSBmcm9tIFwiLi4vc2VtYW50aWMvdmFsaWRhdGUuanNcIlxuaW1wb3J0IHtuZWdvdGlhdGVTdGRsaWJQcm92aWRlcnN9IGZyb20gXCIuLi9zdGRsaWItbmVnb3RpYXRpb24uanNcIlxuaW1wb3J0IHtzdGRsaWJGYWNhZGVQcm9ncmFtRGVzY3JpcHRvciwgc3RkbGliRmFjYWRlUmVnaXN0cnl9IGZyb20gXCIuLi9zdGRsaWItZmFjYWRlcy5qc1wiXG5pbXBvcnQge3N0ZGxpYlByb3ZpZGVyUmVnaXN0cnl9IGZyb20gXCIuLi9zdGRsaWItcHJvdmlkZXJzLmpzXCJcbmltcG9ydCB7cHJlZmxpZ2h0RWZmZWN0Q2FwYWJpbGl0aWVzfSBmcm9tIFwiLi9lZmZlY3RzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVUYXJnZXRCaW5kaW5nSWRlbnRpZmllciwgdmFsaWRhdGVUYXJnZXRJZGVudGlmaWVyLCB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyfSBmcm9tIFwiLi9pZGVudGlmaWVycy5qc1wiXG5pbXBvcnQge2dlbmVyYXRlU3RkbGliUHJvdmlkZXJDb250ZW50fSBmcm9tIFwiLi9zdGRsaWItc3VwcG9ydC5qc1wiXG5pbXBvcnQge3ZhbGlkYXRlQmFja2VuZE1vZHVsZX0gZnJvbSBcIi4vc2hhcmVkLmpzXCJcbmltcG9ydCB7cHJvZ3JhbUltcG9ydE5hbWUsIFNvdXJjZVdyaXRlcn0gZnJvbSBcIi4vd3JpdGVyLmpzXCJcblxuLyoqIEB0eXBlIHtSZWFkb25seTxTZXQ8aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZT4+fSAqL1xuY29uc3QgcHJvZ3JhbVRhcmdldHMgPSBuZXcgU2V0KFtcInBocFwiLCBcInJ1YnlcIiwgXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiLCBcImphdmFcIl0pXG4vKiogQHR5cGUge1JlYWRvbmx5PFNldDxpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2U+Pn0gKi9cbmNvbnN0IHByb2dyYW1BcHBsaWNhdGlvblRhcmdldHMgPSBuZXcgU2V0KFtcImFuZHJvaWRcIiwgXCJpb3NcIl0pXG5cbi8qKlxuICogVmFsaWRhdGVzIGFuZCBwcmVwYXJlcyBhIGNvbXBsZXRlIHNlbWFudGljIHByb2dyYW0gZm9yIGEgbm9uLXRleHQgYmFja2VuZCB3aXRob3V0IGFsbG9jYXRpbmcgYSB3cml0ZXIuXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBCYWNrZW5kIHByZWZsaWdodCByZXF1ZXN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBpbnB1dC5iYWNrZW5kTGFuZ3VhZ2UgLSBFeGlzdGluZyBzZW1hbnRpYyBiYWNrZW5kIHByb2ZpbGUgdG8gZW5mb3JjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBpbnB1dC5kaWFnbm9zdGljTGFuZ3VhZ2UgLSBQdWJsaWMgdGFyZ2V0IGlkZW50aXR5IGZvciBjYXBhYmlsaXR5IGZhaWx1cmVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IGlucHV0LnByb2dyYW0gLSBDb21wbGV0ZSBjYW5kaWRhdGUgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7UmVhZG9ubHk8U2V0PGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2U+Pn0gW2lucHV0LnNvdXJjZUxhbmd1YWdlc10gLSBBY2NlcHRlZCBzb3VyY2UgcHJvdmVuYW5jZSBsYW5ndWFnZXMuXG4gKiBAcmV0dXJucyB7e21vZHVsZXM6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlW10sIHByb2dyYW06IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbSwgc291cmNlczoge2NvbnRlbnQ6IHN0cmluZywgZmlsZW5hbWU6IHN0cmluZywgbGFuZ3VhZ2U/OiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfVtdfX0gUHJlcGFyZWQgaW1tdXRhYmxlLWlucHV0IHZpZXdzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZmxpZ2h0U2VtYW50aWNQcm9ncmFtKHtiYWNrZW5kTGFuZ3VhZ2UsIGRpYWdub3N0aWNMYW5ndWFnZSwgcHJvZ3JhbTogY2FuZGlkYXRlLCBzb3VyY2VMYW5ndWFnZXN9KSB7XG4gIHRyeSB7XG4gICAgY29uc3QgcHJvZ3JhbSA9IHZhbGlkYXRlUHJvZ3JhbShjYW5kaWRhdGUsIGJhY2tlbmRMYW5ndWFnZSwgc291cmNlTGFuZ3VhZ2VzKVxuICAgIGNvbnN0IG1vZHVsZXMgPSBwcmVwYXJlRW1pc3Npb25Nb2R1bGVzKHByb2dyYW0sIGJhY2tlbmRMYW5ndWFnZSlcblxuICAgIHZhbGlkYXRlUHJvZ3JhbVNvdXJjZU93bmVyc2hpcChwcm9ncmFtLCBiYWNrZW5kTGFuZ3VhZ2UpXG4gICAgY29uc3Qgc291cmNlcyA9IHByb2dyYW0uc291cmNlcy5tYXAoKHNvdXJjZSkgPT4ge1xuICAgICAgaWYgKHNvdXJjZS5jb250ZW50ID09PSBudWxsKSBpbnZhbGlkUHJvZ3JhbUdlbmVyYXRpb24oYFByb2dyYW0gc291cmNlICcke3NvdXJjZS5maWxlbmFtZX0nIGhhcyBubyByZXRhaW5lZCBjb250ZW50LmApXG5cbiAgICAgIHJldHVybiB7Y29udGVudDogc291cmNlLmNvbnRlbnQsIGZpbGVuYW1lOiBzb3VyY2UuZmlsZW5hbWUsIC4uLihzb3VyY2UubGFuZ3VhZ2UgPyB7bGFuZ3VhZ2U6IHNvdXJjZS5sYW5ndWFnZX0gOiB7fSl9XG4gICAgfSlcblxuICAgIHJldHVybiB7bW9kdWxlcywgcHJvZ3JhbSwgc291cmNlc31cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZERpYWdub3N0aWMgJiYgZXJyb3IuY29kZSA9PSBcIlVOU1VQUE9SVEVEX0NBUEFCSUxJVFlcIiAmJlxuICAgICAgZXJyb3IubGFuZ3VhZ2UgIT0gZGlhZ25vc3RpY0xhbmd1YWdlKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY2F1c2U6IGVycm9yLFxuICAgICAgICBjb2RlOiBlcnJvci5jb2RlLFxuICAgICAgICBsYW5ndWFnZTogZGlhZ25vc3RpY0xhbmd1YWdlLFxuICAgICAgICBsb2NhdGlvbjogZXJyb3IubG9jYXRpb24sXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLmRldGFpbFxuICAgICAgfSlcbiAgICB9XG4gICAgdGhyb3cgZXJyb3JcbiAgfVxufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIGNvbXBsZXRlIGRldGVybWluaXN0aWMgbWFwcGVkIGFydGlmYWN0IHNldCBmb3Igb25lIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBQcm9ncmFtIGdlbmVyYXRpb24gcmVxdWVzdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBpbnB1dC5sYW5ndWFnZSAtIFJlZ2lzdGVyZWQgcHJvZ3JhbSB0YXJnZXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gaW5wdXQucHJvZ3JhbSAtIENvbXBsZXRlIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge1widGV4dFwiIHwgXCJhcHBsaWNhdGlvblwifSBbaW5wdXQucm9sZV0gLSBFeHBsaWNpdCBhcnRpZmFjdCByb2xlOyBvbWl0dGVkIHByZXNlcnZlcyB0ZXh0IGdlbmVyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLklvc0FwcGxpY2F0aW9uQ29uZmlndXJhdGlvbklucHV0IHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQW5kcm9pZEFwcGxpY2F0aW9uQ29uZmlndXJhdGlvbklucHV0fSBbaW5wdXQuY29uZmlndXJhdGlvbl0gLSBBcHBsaWNhdGlvbiBjb25maWd1cmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Jb3NBcHBsaWNhdGlvbkFzc2V0SW5wdXRbXSB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkFuZHJvaWRBcHBsaWNhdGlvbklucHV0RmlsZVtdfSBbaW5wdXQuYXNzZXRzXSAtIEV4YWN0IGNhbGxlciBhc3NldHMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkFuZHJvaWRBcHBsaWNhdGlvbklucHV0RmlsZVtdfSBbaW5wdXQucmVzb3VyY2VzXSAtIEV4YWN0IEFuZHJvaWQgY2FsbGVyIHJlc291cmNlcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5HZW5lcmF0ZWRBcnRpZmFjdFNldH0gVHJhbnNhY3Rpb25hbGx5IHZhbGlkYXRlZCBhcnRpZmFjdCBzZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZVByb2dyYW1BcnRpZmFjdHMoaW5wdXQpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGlucHV0KSB8fCB0eXBlb2YgaW5wdXQubGFuZ3VhZ2UgIT0gXCJzdHJpbmdcIikgaW52YWxpZFByb2dyYW1HZW5lcmF0aW9uKFwiUHJvZ3JhbSBnZW5lcmF0aW9uIHJlcXVpcmVzIGEgdGFyZ2V0IGxhbmd1YWdlIGFuZCBwcm9ncmFtLlwiKVxuICBjb25zdCByb2xlID0gaW5wdXQucm9sZSA/PyBcInRleHRcIlxuXG4gIGlmIChyb2xlICE9IFwidGV4dFwiICYmIHJvbGUgIT0gXCJhcHBsaWNhdGlvblwiKSBpbnZhbGlkUHJvZ3JhbUdlbmVyYXRpb24oXCJQcm9ncmFtIGFydGlmYWN0IHJvbGUgbXVzdCBiZSAndGV4dCcgb3IgJ2FwcGxpY2F0aW9uJy5cIilcbiAgbGFuZ3VhZ2VSZWdpc3RyeS5yZWNvcmQoaW5wdXQubGFuZ3VhZ2UpXG4gIGlmIChyb2xlID09IFwiYXBwbGljYXRpb25cIikge1xuICAgIGlmICghcHJvZ3JhbUFwcGxpY2F0aW9uVGFyZ2V0cy5oYXMoaW5wdXQubGFuZ3VhZ2UpKSB1bnN1cHBvcnRlZFJvbGUoaW5wdXQubGFuZ3VhZ2UsIFwibXVsdGktZmlsZSBhcHBsaWNhdGlvbiBiYWNrZW5kXCIpXG4gICAgY29uc3QgYmFja2VuZCA9IGxhbmd1YWdlUmVnaXN0cnkucmVzb2x2ZShpbnB1dC5sYW5ndWFnZSwgXCJhcHBsaWNhdGlvbkJhY2tlbmRcIilcblxuICAgIHJldHVybiBjcmVhdGVHZW5lcmF0ZWRBcnRpZmFjdFNldChiYWNrZW5kKGlucHV0KSlcbiAgfVxuICBpZiAoIXByb2dyYW1UYXJnZXRzLmhhcygvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9ICovIChpbnB1dC5sYW5ndWFnZSkpKSB7XG4gICAgdW5zdXBwb3J0ZWRSb2xlKGlucHV0Lmxhbmd1YWdlLCBcIm11bHRpLWZpbGUgdGV4dCBiYWNrZW5kXCIpXG4gIH1cbiAgY29uc3QgbGFuZ3VhZ2UgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9ICovIChpbnB1dC5sYW5ndWFnZSlcbiAgY29uc3QgcHJvZ3JhbSA9IHZhbGlkYXRlUHJvZ3JhbShpbnB1dC5wcm9ncmFtLCBsYW5ndWFnZSlcbiAgY29uc3QgbGlua2luZyA9IHBsYW5TdGRsaWJMaW5raW5nKHByb2dyYW0sIGxhbmd1YWdlKVxuICBjb25zdCBlbWlzc2lvbk1vZHVsZXMgPSBwcmVwYXJlRW1pc3Npb25Nb2R1bGVzKHByb2dyYW0sIGxhbmd1YWdlLCBsaW5raW5nKVxuICB2YWxpZGF0ZVByb2dyYW1Tb3VyY2VPd25lcnNoaXAocHJvZ3JhbSwgbGFuZ3VhZ2UpXG4gIGNvbnN0IHBhdGhzID0gcGxhbk1vZHVsZVBhdGhzKHByb2dyYW0sIGxhbmd1YWdlLCBsaW5raW5nKVxuICBjb25zdCBzb3VyY2VzID0gcHJvZ3JhbS5zb3VyY2VzLm1hcCgoc291cmNlKSA9PiB7XG4gICAgaWYgKHNvdXJjZS5jb250ZW50ID09PSBudWxsKSBpbnZhbGlkUHJvZ3JhbUdlbmVyYXRpb24oYFByb2dyYW0gc291cmNlICcke3NvdXJjZS5maWxlbmFtZX0nIGhhcyBubyByZXRhaW5lZCBjb250ZW50LmApXG5cbiAgICByZXR1cm4ge2NvbnRlbnQ6IHNvdXJjZS5jb250ZW50LCBmaWxlbmFtZTogc291cmNlLmZpbGVuYW1lLCAuLi4oc291cmNlLmxhbmd1YWdlID8ge2xhbmd1YWdlOiBzb3VyY2UubGFuZ3VhZ2V9IDoge30pfVxuICB9KVxuICBjb25zdCBiYWNrZW5kID0gLyoqIEB0eXBlIHt0eXBlb2YgaW1wb3J0KFwiLi9qYXZhc2NyaXB0LmpzXCIpLmdlbmVyYXRlSmF2YVNjcmlwdH0gKi8gKFxuICAgIGxhbmd1YWdlUmVnaXN0cnkucmVzb2x2ZShsYW5ndWFnZSwgXCJ0ZXh0QmFja2VuZFwiKSlcbiAgY29uc3QgbWVkaWFUeXBlID0gbGFuZ3VhZ2VSZWdpc3RyeS5yZWNvcmQobGFuZ3VhZ2UpLm1lZGlhVHlwZVxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkdlbmVyYXRlZFNldEFydGlmYWN0W119ICovXG4gIGNvbnN0IGFydGlmYWN0cyA9IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiID8gW3tcbiAgICBjb250ZW50OiBcIntcXG4gIFxcXCJ0eXBlXFxcIjogXFxcIm1vZHVsZVxcXCJcXG59XFxuXCIsXG4gICAgY29udGVudEtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInRleHRcIiksXG4gICAgbWVkaWFUeXBlOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICBvd25lcnNoaXA6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcImdlbmVyYXRlZFwiKSxcbiAgICBwYXRoOiBcInBhY2thZ2UuanNvblwiLFxuICAgIHByb3ZlbmFuY2U6IHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInN5bnRoZXRpY1wiKSxcbiAgICAgIHJlYXNvbjogXCJEZWNsYXJlcyB0aGUgZ2VuZXJhdGVkIEphdmFTY3JpcHQtZmFtaWx5IGFydGlmYWN0IHNldCBhcyBjYW5vbmljYWwgRVNNLlwiLFxuICAgICAgcmVsYXRlZE9yaWdpbnM6IFtdXG4gICAgfSxcbiAgICByb2xlOiBcIm1hbmlmZXN0XCJcbiAgfV0gOiBbXVxuXG4gIGlmIChsaW5raW5nICYmIGxhbmd1YWdlICE9IFwiamF2YVwiKSB7XG4gICAgZm9yIChjb25zdCBwcm92aWRlciBvZiBsaW5raW5nLm5lZ290aWF0aW9uLnByb3ZpZGVycykge1xuICAgICAgY29uc3QgcmVjb3JkID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zdGRsaWItcHJvdmlkZXJzLmpzXCIpLlN0ZGxpYlByb3ZpZGVyUmVjb3JkfSAqLyAobGlua2luZy5yZWNvcmRzLmdldChwcm92aWRlci5tb2R1bGUpKVxuXG4gICAgICBhcnRpZmFjdHMucHVzaCh7XG4gICAgICAgIGNvbnRlbnQ6IGdlbmVyYXRlU3RkbGliUHJvdmlkZXJDb250ZW50KC8qKiBAdHlwZSB7XCJwaHBcIiB8IFwicnVieVwiIHwgXCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gKi8gKGxhbmd1YWdlKSxcbiAgICAgICAgICBbLi4ucHJvdmlkZXIub3BlcmF0aW9uc10sIHByb3ZpZGVyLm1vZHVsZSksXG4gICAgICAgIGNvbnRlbnRLaW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ0ZXh0XCIpLFxuICAgICAgICBtZWRpYVR5cGU6IHJlY29yZC5hcnRpZmFjdC5tZWRpYVR5cGUsXG4gICAgICAgIG93bmVyc2hpcDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiZ2VuZXJhdGVkXCIpLFxuICAgICAgICBwYXRoOiByZWNvcmQuYXJ0aWZhY3QucGF0aCxcbiAgICAgICAgcHJvdmVuYW5jZToge1xuICAgICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInN5bnRoZXRpY1wiKSxcbiAgICAgICAgICByZWFzb246IGBzZW1hbnRpZm9sZC1zdGRsaWItcHJvdmlkZXI6JHtyZWNvcmQuaWRlbnRpdHl9YCxcbiAgICAgICAgICByZWxhdGVkT3JpZ2luczogW11cbiAgICAgICAgfSxcbiAgICAgICAgcm9sZTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwic3VwcG9ydFwiKVxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGVtaXNzaW9uTW9kdWxlIG9mIGVtaXNzaW9uTW9kdWxlcykge1xuICAgIGNvbnN0IG1vZHVsZUlkID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChSZWZsZWN0LmdldChlbWlzc2lvbk1vZHVsZSwgXCJpZFwiKSlcbiAgICBjb25zdCBmaWxlbmFtZSA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocGF0aHMuZ2V0KG1vZHVsZUlkKSlcbiAgICBjb25zdCB3cml0ZXIgPSBuZXcgU291cmNlV3JpdGVyKHtcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgbGFuZ3VhZ2UsXG4gICAgICBtb2R1bGU6IGVtaXNzaW9uTW9kdWxlLFxuICAgICAgcHJvZ3JhbSxcbiAgICAgIHByb2dyYW1QYXRoczogcGF0aHMsXG4gICAgICBzb3VyY2VzLFxuICAgICAgLi4uKGxpbmtpbmcgJiYgZW1pc3Npb25Nb2R1bGUuY2FwYWJpbGl0aWVzICE9PSB1bmRlZmluZWQgPyB7XG4gICAgICAgIHN0ZGxpYlByb3ZpZGVyRW50cmllczogT2JqZWN0LmZyb21FbnRyaWVzKChsaW5raW5nLnVzZWRPcGVyYXRpb25zQnlNb2R1bGUuZ2V0KG1vZHVsZUlkKSA/PyBbXSkubWFwKCh7bW9kdWxlLCBvcGVyYXRpb259KSA9PiBbXG4gICAgICAgICAgcXVhbGlmaWVkT3BlcmF0aW9uS2V5KG1vZHVsZSwgb3BlcmF0aW9uKSxcbiAgICAgICAgICAvKiogQHR5cGUge3N0cmluZ30gKi8gKGxpbmtpbmcucmVjb3Jkcy5nZXQobW9kdWxlKT8ubmF0aXZlRW50cmllc1tvcGVyYXRpb25dKVxuICAgICAgICBdKSksXG4gICAgICAgIHN0ZGxpYlByb3ZpZGVySW1wb3J0czogbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgfHwgbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgP1xuICAgICAgICAgIGxpbmtpbmcucHJvdmlkZXJJbXBvcnRzQnlNb2R1bGUuZ2V0KG1vZHVsZUlkKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgc3RkbGliUHJvdmlkZXJQYXRoczogbGlua2luZy5wcm92aWRlclBhdGhzQnlNb2R1bGUuZ2V0KG1vZHVsZUlkKSxcbiAgICAgICAgLi4uKGxhbmd1YWdlID09IFwiamF2YVwiID8ge1xuICAgICAgICAgIHN0ZGxpYlByb3ZpZGVyT3duZXJNb2R1bGU6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobGlua2luZy5vd25lck1vZHVsZUlkKSxcbiAgICAgICAgICBzdGRsaWJQcm92aWRlclNoaW1zOiBtb2R1bGVJZCA9PSBsaW5raW5nLm93bmVyTW9kdWxlSWQgPyBsaW5raW5nLnVzZWRPcGVyYXRpb25zLm1hcCgoe29wZXJhdGlvbn0pID0+IG9wZXJhdGlvbikgOiB1bmRlZmluZWRcbiAgICAgICAgfSA6IHt9KVxuICAgICAgfSA6IHt9KVxuICAgIH0pXG5cbiAgICBiYWNrZW5kKGVtaXNzaW9uTW9kdWxlLCB3cml0ZXIpXG4gICAgY29uc3QgbWFwcGluZyA9IGZpbmFsaXplTWFwcGluZyh3cml0ZXIuZmluaXNoKCkpXG5cbiAgICBhcnRpZmFjdHMucHVzaCh7XG4gICAgICBjb250ZW50OiBtYXBwaW5nLmdlbmVyYXRlZC5jb250ZW50LFxuICAgICAgY29udGVudEtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInRleHRcIiksXG4gICAgICBtZWRpYVR5cGU6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAobWVkaWFUeXBlKSxcbiAgICAgIG93bmVyc2hpcDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiZ2VuZXJhdGVkXCIpLFxuICAgICAgcGF0aDogZmlsZW5hbWUsXG4gICAgICBwcm92ZW5hbmNlOiB7XG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInRleHRcIiksXG4gICAgICAgIG1hcHBpbmcsXG4gICAgICAgIHNvdXJjZU1hcDogdG9Tb3VyY2VNYXBWMyhtYXBwaW5nKSxcbiAgICAgICAgc291cmNlTWFwRmlsZW5hbWU6IGAke2ZpbGVuYW1lfS5tYXBgXG4gICAgICB9LFxuICAgICAgcm9sZTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5HZW5lcmF0ZWRBcnRpZmFjdFJvbGV9ICovIChcbiAgICAgICAgbW9kdWxlSWQgPT0gcHJvZ3JhbS5lbnRyeU1vZHVsZSA/IFwiZW50cnlcIiA6IFJlZmxlY3QuZ2V0KGVtaXNzaW9uTW9kdWxlLCBcInN0ZGxpYkZhY2FkZVwiKSA/IFwic3VwcG9ydFwiIDogXCJzb3VyY2VcIilcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUdlbmVyYXRlZEFydGlmYWN0U2V0KHtcbiAgICBhcnRpZmFjdHMsXG4gICAgLi4uKGxpbmtpbmcgfHwgcHJvZ3JhbS5zdGRsaWJGYWNhZGVzID8ge21ldGFkYXRhOiBzdGRsaWJMaW5rTWV0YWRhdGEobGlua2luZywgcGF0aHMsIHByb2dyYW0uc3RkbGliRmFjYWRlcyl9IDoge30pLFxuICAgIHRhcmdldDogbGFuZ3VhZ2VcbiAgfSlcbn1cblxuLyoqXG4gKiBAdHlwZWRlZiBTdGRsaWJQcm9ncmFtTGlua2luZ1xuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zdGRsaWItbmVnb3RpYXRpb24uanNcIikuU3RkbGliTmVnb3RpYXRpb25SZXN1bHR9IG5lZ290aWF0aW9uIC0gTmVnb3RpYXRlZCBwcm92aWRlciBjbG9zdXJlLlxuICogQHByb3BlcnR5IHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zdGRsaWItcHJvdmlkZXJzLmpzXCIpLlN0ZGxpYlByb3ZpZGVyUmVjb3JkPn0gcmVjb3JkcyAtIE1hdGVyaWFsaXplZCBwcm92aWRlciByZWNvcmRzIGJ5IGNhbm9uaWNhbCBtb2R1bGUuXG4gKiBAcHJvcGVydHkge1F1YWxpZmllZFN0ZGxpYk9wZXJhdGlvbltdfSB1c2VkT3BlcmF0aW9ucyAtIFByb2dyYW0td2lkZSB1c2VkIGNhbm9uaWNhbCBvcGVyYXRpb25zIGluIHN0YWJsZSBvcmRlci5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgUXVhbGlmaWVkU3RkbGliT3BlcmF0aW9uW10+fSB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlIC0gVXNlZCBjYW5vbmljYWwgb3BlcmF0aW9ucyBieSBwcm9ncmFtIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgc3RyaW5nW10+fSBwcm92aWRlckltcG9ydHNCeU1vZHVsZSAtIE9yZGVyZWQgcHJvdmlkZXIgaW1wb3J0IG5hbWVzIGJ5IG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgc3RyaW5nW10+fSBwcm92aWRlclBhdGhzQnlNb2R1bGUgLSBQcm92aWRlciBhcnRpZmFjdCBjbG9zdXJlIGJ5IHByb2dyYW0gbW9kdWxlIGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtzdHJpbmcgfCBudWxsfSBvd25lck1vZHVsZUlkIC0gSmF2YSB0YXJnZXQ6IGZpcnN0IG9wZXJhdGlvbi11c2luZyBtb2R1bGUgaWRlbnRpdHkgaG9zdGluZyB0aGUgc2hhcmVkIHN1cHBvcnQ7IG51bGwgZm9yIGFydGlmYWN0LW1hdGVyaWFsaXppbmcgdGFyZ2V0cy5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFF1YWxpZmllZFN0ZGxpYk9wZXJhdGlvblxuICogQHByb3BlcnR5IHtzdHJpbmd9IG1vZHVsZSAtIENhbm9uaWNhbCBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gb3BlcmF0aW9uIC0gQ2Fub25pY2FsIG9wZXJhdGlvbiBuYW1lLlxuICovXG5cbi8qKlxuICogUGxhbnMgdGhlIGxpbmtlZCBzdGRsaWIgcHJvdmlkZXIgZm9yIG9uZSBwcm9ncmFtLCBvciByZXBvcnRzIHRoYXQgbm8gb3BlcmF0aW9uIGlzIHVzZWQuXG4gKiBKYXZhIHJlc29sdmVzIHRoZSBzYW1lIG5lZ290aWF0ZWQgcHJvdmlkZXIgcmVjb3JkIGJ1dCBob3N0cyBpdHMgc3VwcG9ydCBpbiB0aGUgZmlyc3RcbiAqIG9wZXJhdGlvbi11c2luZyBtb2R1bGUgaW5zdGVhZCBvZiBhIHNlcGFyYXRlIHByb3ZpZGVyIGFydGlmYWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IHByb2dyYW0gLSBWYWxpZGF0ZWQgc2VtYW50aWMgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7U3RkbGliUHJvZ3JhbUxpbmtpbmcgfCBudWxsfSBMaW5raW5nIHBsYW4sIG9yIG51bGwgd2hlbiBub3RoaW5nIGlzIHVzZWQuXG4gKi9cbmZ1bmN0aW9uIHBsYW5TdGRsaWJMaW5raW5nKHByb2dyYW0sIGxhbmd1YWdlKSB7XG4gIGNvbnN0IHtwcm9ncmFtV2lkZSwgdXNlZE9wZXJhdGlvbnNCeU1vZHVsZX0gPSBjb2xsZWN0VXNlZEVmZmVjdE9wZXJhdGlvbnMocHJvZ3JhbSlcblxuICBpZiAocHJvZ3JhbVdpZGUubGVuZ3RoID09IDApIHJldHVybiBudWxsXG4gIGNvbnN0IGNvbnRyYWN0cyA9IHByb2dyYW0uc3RkbGliQ29udHJhY3RzID8/IFsvKiogQHR5cGUge3tpZGVudGl0eTogc3RyaW5nLCBjb250cmFjdFZlcnNpb24/OiBzdHJpbmd9fSAqLyAocHJvZ3JhbS5zdGRsaWJDb250cmFjdCldXG4gIGNvbnN0IGNvbnRyYWN0c0J5SWRlbnRpdHkgPSBuZXcgTWFwKGNvbnRyYWN0cy5tYXAoKGNvbnRyYWN0KSA9PiBbY29udHJhY3QuaWRlbnRpdHksIGNvbnRyYWN0XSkpXG4gIGNvbnN0IHJlcXVpcmVtZW50c0J5TW9kdWxlID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBxdWFsaWZpZWQgb2YgcHJvZ3JhbVdpZGUpIHtcbiAgICBjb25zdCByZXF1aXJlbWVudCA9IHJlcXVpcmVtZW50c0J5TW9kdWxlLmdldChxdWFsaWZpZWQubW9kdWxlKSA/PyBbXVxuXG4gICAgcmVxdWlyZW1lbnQucHVzaChxdWFsaWZpZWQub3BlcmF0aW9uKVxuICAgIHJlcXVpcmVtZW50c0J5TW9kdWxlLnNldChxdWFsaWZpZWQubW9kdWxlLCByZXF1aXJlbWVudClcbiAgfVxuICBjb25zdCBuZWdvdGlhdGlvbiA9IG5lZ290aWF0ZVN0ZGxpYlByb3ZpZGVycyh7XG4gICAgcmVxdWlyZW1lbnRzOiBbLi4ucmVxdWlyZW1lbnRzQnlNb2R1bGVdLm1hcCgoW21vZHVsZSwgb3BlcmF0aW9uc10pID0+IHtcbiAgICAgIGNvbnN0IGNvbnRyYWN0ID0gY29udHJhY3RzQnlJZGVudGl0eS5nZXQobW9kdWxlKVxuXG4gICAgICBpZiAoIWNvbnRyYWN0KSB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBgUmVhY2hhYmxlIGNhbm9uaWNhbCBvcGVyYXRpb24gJyR7bW9kdWxlfS4ke29wZXJhdGlvbnNbMF19JyBoYXMgbm8gZGVjbGFyZWQgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdC5gXG4gICAgICB9KVxuICAgICAgcmV0dXJuIHttb2R1bGUsIG9wZXJhdGlvbnMsIC4uLihjb250cmFjdC5jb250cmFjdFZlcnNpb24gIT09IHVuZGVmaW5lZCA/IHtyYW5nZTogY29udHJhY3QuY29udHJhY3RWZXJzaW9ufSA6IHt9KX1cbiAgICB9KSxcbiAgICB0YXJnZXQ6IGxhbmd1YWdlXG4gIH0pXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiKS5TdGRsaWJQcm92aWRlclJlY29yZD59ICovXG4gIGNvbnN0IHJlY29yZHMgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IHNlbGVjdGVkIG9mIG5lZ290aWF0aW9uLm1vZHVsZXMpIHtcbiAgICBjb25zdCBjYW5kaWRhdGVzID0gc3RkbGliUHJvdmlkZXJSZWdpc3RyeS5wcm92aWRlcnNGb3IobGFuZ3VhZ2UsIHNlbGVjdGVkLmlkZW50aXR5LCBzZWxlY3RlZC52ZXJzaW9uKVxuXG4gICAgaWYgKGNhbmRpZGF0ZXMubGVuZ3RoICE9IDEpIHtcbiAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICBjb2RlOiBcIlNURExJQl9MSU5LX0ZBSUxVUkVcIixcbiAgICAgICAgbGFuZ3VhZ2UsXG4gICAgICAgIG1lc3NhZ2U6IGBFeHBlY3RlZCBleGFjdGx5IG9uZSByZWdpc3RlcmVkIHN0ZGxpYiBwcm92aWRlciBmb3IgJyR7c2VsZWN0ZWQuaWRlbnRpdHl9JyBvbiAnJHtsYW5ndWFnZX0nLmBcbiAgICAgIH0pXG4gICAgfVxuICAgIHJlY29yZHMuc2V0KHNlbGVjdGVkLmlkZW50aXR5LCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3N0ZGxpYi1wcm92aWRlcnMuanNcIikuU3RkbGliUHJvdmlkZXJSZWNvcmR9ICovIChjYW5kaWRhdGVzWzBdKSlcbiAgfVxuICBjb25zdCBvd25lck1vZHVsZUlkID0gbGFuZ3VhZ2UgPT0gXCJqYXZhXCJcbiAgICA/IHByb2dyYW0ubW9kdWxlcy5tYXAoKG1vZHVsZSkgPT4gbW9kdWxlLmlkKS5maW5kKChpZCkgPT4gKHVzZWRPcGVyYXRpb25zQnlNb2R1bGUuZ2V0KGlkKSA/PyBbXSkubGVuZ3RoID4gMClcbiAgICA6IG51bGxcblxuICBpZiAob3duZXJNb2R1bGVJZCA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICBjb2RlOiBcIlNURExJQl9MSU5LX0ZBSUxVUkVcIixcbiAgICBsYW5ndWFnZSxcbiAgICBtZXNzYWdlOiBcIkphdmEgcHJvZ3JhbSBsaW5raW5nIHJlcXVpcmVzIG9uZSBtb2R1bGUgdXNpbmcgY2Fub25pY2FsIG9wZXJhdGlvbnMuXCJcbiAgfSlcblxuICByZXR1cm4ge1xuICAgIG5lZ290aWF0aW9uLFxuICAgIG93bmVyTW9kdWxlSWQsXG4gICAgcHJvdmlkZXJJbXBvcnRzQnlNb2R1bGU6IGNvbGxlY3RQcm92aWRlckltcG9ydHMocHJvZ3JhbSwgbmVnb3RpYXRpb24sIHJlY29yZHMsIHVzZWRPcGVyYXRpb25zQnlNb2R1bGUsIGxhbmd1YWdlLCBvd25lck1vZHVsZUlkKSxcbiAgICBwcm92aWRlclBhdGhzQnlNb2R1bGU6IGNvbGxlY3RQcm92aWRlclBhdGhzKG5lZ290aWF0aW9uLCByZWNvcmRzLCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlKSxcbiAgICByZWNvcmRzLFxuICAgIHVzZWRPcGVyYXRpb25zOiBbLi4ucHJvZ3JhbVdpZGVdLFxuICAgIHVzZWRPcGVyYXRpb25zQnlNb2R1bGVcbiAgfVxufVxuXG4vKipcbiAqIFNlbGVjdHMgdGhlIGV4YWN0IHByb3ZpZGVyL3R5cGUgZGVwZW5kZW5jeSBjbG9zdXJlIHJlcXVpcmVkIGJ5IGVhY2ggZW1pdHRpbmcgcHJvZ3JhbSBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0ZGxpYi1uZWdvdGlhdGlvbi5qc1wiKS5TdGRsaWJOZWdvdGlhdGlvblJlc3VsdH0gbmVnb3RpYXRpb24gLSBOZWdvdGlhdGVkIHByb2dyYW0gY2xvc3VyZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiKS5TdGRsaWJQcm92aWRlclJlY29yZD59IHJlY29yZHMgLSBTZWxlY3RlZCBwcm92aWRlciByZWNvcmRzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25bXT59IHVzZWRPcGVyYXRpb25zQnlNb2R1bGUgLSBSZWFjaGFibGUgb3BlcmF0aW9ucyBieSBwcm9ncmFtIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBzdHJpbmdbXT59IE9yZGVyZWQgcHJvdmlkZXIgcGF0aHMgYnkgcHJvZ3JhbSBtb2R1bGUuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3RQcm92aWRlclBhdGhzKG5lZ290aWF0aW9uLCByZWNvcmRzLCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlKSB7XG4gIGNvbnN0IHBhdGhzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBbbW9kdWxlSWQsIG9wZXJhdGlvbnNdIG9mIHVzZWRPcGVyYXRpb25zQnlNb2R1bGUpIHtcbiAgICBjb25zdCBzZWxlY3RlZCA9IG5ldyBTZXQob3BlcmF0aW9ucy5tYXAoKHttb2R1bGV9KSA9PiBtb2R1bGUpKVxuICAgIGxldCBjaGFuZ2VkID0gdHJ1ZVxuXG4gICAgd2hpbGUgKGNoYW5nZWQpIHtcbiAgICAgIGNoYW5nZWQgPSBmYWxzZVxuICAgICAgZm9yIChjb25zdCBtb2R1bGUgb2YgWy4uLnNlbGVjdGVkXSkge1xuICAgICAgICBmb3IgKGNvbnN0IGRlcGVuZGVuY3kgb2YgcmVjb3Jkcy5nZXQobW9kdWxlKT8uZGVwZW5kZW5jaWVzID8/IFtdKSB7XG4gICAgICAgICAgaWYgKCFzZWxlY3RlZC5oYXMoZGVwZW5kZW5jeS5tb2R1bGUpKSB7XG4gICAgICAgICAgICBzZWxlY3RlZC5hZGQoZGVwZW5kZW5jeS5tb2R1bGUpXG4gICAgICAgICAgICBjaGFuZ2VkID0gdHJ1ZVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBwYXRocy5zZXQobW9kdWxlSWQsIG5lZ290aWF0aW9uLnByb3ZpZGVycy5maWx0ZXIoKHttb2R1bGV9KSA9PiBzZWxlY3RlZC5oYXMobW9kdWxlKSkubWFwKCh7bW9kdWxlfSkgPT5cbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc3RkbGliLXByb3ZpZGVycy5qc1wiKS5TdGRsaWJQcm92aWRlclJlY29yZH0gKi8gKHJlY29yZHMuZ2V0KG1vZHVsZSkpLmFydGlmYWN0LnBhdGgpKVxuICB9XG4gIHJldHVybiBwYXRoc1xufVxuXG4vKipcbiAqIENvbGxlY3RzIHRoZSBjYW5vbmljYWwgb3BlcmF0aW9ucyBpbnZva2VkIGJ5IGVhY2ggcHJvZ3JhbSBtb2R1bGUgaW4gc3RhYmxlIG9yZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IHByb2dyYW0gLSBWYWxpZGF0ZWQgc2VtYW50aWMgcHJvZ3JhbS5cbiAqIEByZXR1cm5zIHt7cHJvZ3JhbVdpZGU6IFF1YWxpZmllZFN0ZGxpYk9wZXJhdGlvbltdLCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlOiBNYXA8c3RyaW5nLCBRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25bXT59fSBVc2VkIG9wZXJhdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3RVc2VkRWZmZWN0T3BlcmF0aW9ucyhwcm9ncmFtKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgUXVhbGlmaWVkU3RkbGliT3BlcmF0aW9uW10+fSAqL1xuICBjb25zdCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlID0gbmV3IE1hcCgpXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgUXVhbGlmaWVkU3RkbGliT3BlcmF0aW9uPn0gKi9cbiAgY29uc3QgcHJvZ3JhbVdpZGUgPSBuZXcgTWFwKClcbiAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCB7Ym9keTogdW5rbm93biwgbW9kdWxlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9Pn0gKi9cbiAgY29uc3QgYm9kaWVzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgcHJvZ3JhbS5tb2R1bGVzKSB7XG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSBib2RpZXMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCB7Ym9keTogZGVjbGFyYXRpb24uYm9keSwgbW9kdWxlfSlcbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5jbGFzc2VzID8/IFtdKSB7XG4gICAgICBib2RpZXMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uY29uc3RydWN0b3IuaWQpLCB7Ym9keTogZGVjbGFyYXRpb24uY29uc3RydWN0b3IuYm9keSwgbW9kdWxlfSlcbiAgICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIGJvZGllcy5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChtZXRob2QuaWQpLCB7Ym9keTogbWV0aG9kLmJvZHksIG1vZHVsZX0pXG4gICAgfVxuICAgIHVzZWRPcGVyYXRpb25zQnlNb2R1bGUuc2V0KG1vZHVsZS5pZCwgW10pXG4gIH1cbiAgY29uc3QgZW50cnlNb2R1bGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gKi8gKFxuICAgIHByb2dyYW0ubW9kdWxlcy5maW5kKCh7aWR9KSA9PiBpZCA9PSBwcm9ncmFtLmVudHJ5TW9kdWxlKSlcbiAgLyoqIEB0eXBlIHt7Ym9keTogdW5rbm93biwgbW9kdWxlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9W119ICovXG4gIGNvbnN0IHBlbmRpbmcgPSBbe2JvZHk6IGVudHJ5TW9kdWxlLmVudHJ5UG9pbnQ/LmJvZHksIG1vZHVsZTogZW50cnlNb2R1bGV9XVxuICBjb25zdCByZWFjaGVkRGVjbGFyYXRpb25zID0gbmV3IFNldCgpXG5cbiAgd2hpbGUgKHBlbmRpbmcubGVuZ3RoID4gMCkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSAvKiogQHR5cGUge3tib2R5OiB1bmtub3duLCBtb2R1bGU6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX19ICovIChwZW5kaW5nLnNoaWZ0KCkpXG4gICAgY29uc3Qgb3BlcmF0aW9uTmFtZXMgPSBuZXcgTWFwKGN1cnJlbnQubW9kdWxlLmNhcGFiaWxpdGllcz8uZmxhdE1hcCgoY2FwYWJpbGl0eSkgPT5cbiAgICAgIGNhcGFiaWxpdHkub3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbikgPT4gW29wZXJhdGlvbi5pZCwge21vZHVsZTogY2FwYWJpbGl0eS5hdXRob3JpdHlJZCwgb3BlcmF0aW9uOiBvcGVyYXRpb24ubmFtZX1dKSkgPz8gW10pXG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKVxuXG4gICAgLyoqXG4gICAgICogVmlzaXRzIG9uZSByZWFjaGFibGUgc2VtYW50aWMgc3VidHJlZS5cbiAgICAgKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHNlbWFudGljIHN1YnRyZWUuXG4gICAgICovXG4gICAgY29uc3QgdmlzaXQgPSAodmFsdWUpID0+IHtcbiAgICAgIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXModmFsdWUpKSByZXR1cm5cbiAgICAgIHNlZW4uYWRkKHZhbHVlKVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJraW5kXCIpXG5cbiAgICAgICAgaWYgKGtpbmQgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICAgICAgY29uc3Qgb3BlcmF0aW9uID0gUmVmbGVjdC5nZXQodmFsdWUsIFwib3BlcmF0aW9uXCIpXG5cbiAgICAgICAgICBpZiAodHlwZW9mIG9wZXJhdGlvbiA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBjb25zdCBxdWFsaWZpZWQgPSBvcGVyYXRpb25OYW1lcy5nZXQob3BlcmF0aW9uKVxuXG4gICAgICAgICAgICBpZiAocXVhbGlmaWVkICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgY29uc3Qga2V5ID0gcXVhbGlmaWVkT3BlcmF0aW9uS2V5KHF1YWxpZmllZC5tb2R1bGUsIHF1YWxpZmllZC5vcGVyYXRpb24pXG4gICAgICAgICAgICAgIGNvbnN0IG1vZHVsZU9wZXJhdGlvbnMgPSAvKiogQHR5cGUge1F1YWxpZmllZFN0ZGxpYk9wZXJhdGlvbltdfSAqLyAodXNlZE9wZXJhdGlvbnNCeU1vZHVsZS5nZXQoY3VycmVudC5tb2R1bGUuaWQpKVxuXG4gICAgICAgICAgICAgIGlmICghbW9kdWxlT3BlcmF0aW9ucy5zb21lKChpdGVtKSA9PiBxdWFsaWZpZWRPcGVyYXRpb25LZXkoaXRlbS5tb2R1bGUsIGl0ZW0ub3BlcmF0aW9uKSA9PSBrZXkpKSBtb2R1bGVPcGVyYXRpb25zLnB1c2gocXVhbGlmaWVkKVxuICAgICAgICAgICAgICBwcm9ncmFtV2lkZS5zZXQoa2V5LCBxdWFsaWZpZWQpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGRlY2xhcmF0aW9uSWQgPSBpc1BsYWluT2JqZWN0KFJlZmxlY3QuZ2V0KHZhbHVlLCBcInJlc29sdXRpb25cIikpXG4gICAgICAgICAgPyBSZWZsZWN0LmdldChSZWZsZWN0LmdldCh2YWx1ZSwgXCJyZXNvbHV0aW9uXCIpLCBcImRlY2xhcmF0aW9uSWRcIikgOiB1bmRlZmluZWRcblxuICAgICAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uSWQgPT0gXCJzdHJpbmdcIiAmJiAhcmVhY2hlZERlY2xhcmF0aW9ucy5oYXMoZGVjbGFyYXRpb25JZCkpIHtcbiAgICAgICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGJvZGllcy5nZXQoZGVjbGFyYXRpb25JZClcblxuICAgICAgICAgIGlmIChkZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgcmVhY2hlZERlY2xhcmF0aW9ucy5hZGQoZGVjbGFyYXRpb25JZClcbiAgICAgICAgICAgIHBlbmRpbmcucHVzaChkZWNsYXJhdGlvbilcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICAgICAgaWYgKFtcImNhcGFiaWxpdGllc1wiLCBcImxvY2F0aW9uXCIsIFwicHJvdmVuYW5jZVwiLCBcInJlc29sdXRpb25cIiwgXCJzb3VyY2VQcm92ZW5hbmNlXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICAgICAgdmlzaXQoY2hpbGQpXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBmb3IgKGNvbnN0IGNoaWxkIG9mIHZhbHVlKSB2aXNpdChjaGlsZClcbiAgICB9XG5cbiAgICB2aXNpdChjdXJyZW50LmJvZHkpXG4gIH1cbiAgZm9yIChjb25zdCBvcGVyYXRpb25zIG9mIHVzZWRPcGVyYXRpb25zQnlNb2R1bGUudmFsdWVzKCkpIHtcbiAgICBvcGVyYXRpb25zLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiBxdWFsaWZpZWRPcGVyYXRpb25LZXkobGVmdC5tb2R1bGUsIGxlZnQub3BlcmF0aW9uKVxuICAgICAgLmxvY2FsZUNvbXBhcmUocXVhbGlmaWVkT3BlcmF0aW9uS2V5KHJpZ2h0Lm1vZHVsZSwgcmlnaHQub3BlcmF0aW9uKSwgXCJlblwiKSlcbiAgfVxuICByZXR1cm4ge3Byb2dyYW1XaWRlOiBbLi4ucHJvZ3JhbVdpZGUudmFsdWVzKCldLnNvcnQoKGxlZnQsIHJpZ2h0KSA9PiBxdWFsaWZpZWRPcGVyYXRpb25LZXkobGVmdC5tb2R1bGUsIGxlZnQub3BlcmF0aW9uKVxuICAgIC5sb2NhbGVDb21wYXJlKHF1YWxpZmllZE9wZXJhdGlvbktleShyaWdodC5tb2R1bGUsIHJpZ2h0Lm9wZXJhdGlvbiksIFwiZW5cIikpLCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlfVxufVxuXG4vKipcbiAqIEJ1aWxkcyBhbiB1bmFtYmlndW91cyBpbnRlcm5hbCBrZXkgZm9yIG9uZSBjYW5vbmljYWwgb3BlcmF0aW9uIGF1dGhvcml0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGUgLSBDYW5vbmljYWwgbW9kdWxlIGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IG9wZXJhdGlvbiAtIENhbm9uaWNhbCBvcGVyYXRpb24gbmFtZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFF1YWxpZmllZCBpbnRlcm5hbCBrZXkuXG4gKi9cbmZ1bmN0aW9uIHF1YWxpZmllZE9wZXJhdGlvbktleShtb2R1bGUsIG9wZXJhdGlvbikge1xuICByZXR1cm4gYCR7bW9kdWxlfVxcdTAwMDAke29wZXJhdGlvbn1gXG59XG5cbi8qKlxuICogQ29sbGVjdHMgdGhlIG9yZGVyZWQgcHJvdmlkZXIgaW1wb3J0IG5hbWVzIGVhY2ggbW9kdWxlIG11c3QgcHVsbCBmcm9tIHRoZSBsaW5rZWQgcHJvdmlkZXIuXG4gKiBKYXZhIG1vZHVsZXMgbGlzdCByZWZlcmVuY2VkIGNhcGFiaWxpdHkgdHlwZSBuYW1lcyBvbmx5OyB0aGUgb3duZXIgbGlzdHMgbm9uZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gVmFsaWRhdGVkIHNlbWFudGljIHByb2dyYW0uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0ZGxpYi1uZWdvdGlhdGlvbi5qc1wiKS5TdGRsaWJOZWdvdGlhdGlvblJlc3VsdH0gbmVnb3RpYXRpb24gLSBOZWdvdGlhdGVkIGNsb3N1cmUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3N0ZGxpYi1wcm92aWRlcnMuanNcIikuU3RkbGliUHJvdmlkZXJSZWNvcmQ+fSByZWNvcmRzIC0gUHJvdmlkZXIgcmVjb3JkcyBieSBjYW5vbmljYWwgbW9kdWxlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBRdWFsaWZpZWRTdGRsaWJPcGVyYXRpb25bXT59IHVzZWRPcGVyYXRpb25zQnlNb2R1bGUgLSBVc2VkIGNhbm9uaWNhbCBvcGVyYXRpb25zIGJ5IG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bGx9IFtvd25lck1vZHVsZUlkXSAtIEphdmEgb3duZXIgbW9kdWxlIGlkZW50aXR5LlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIHN0cmluZ1tdPn0gT3JkZXJlZCBwcm92aWRlciBpbXBvcnQgbmFtZXMgYnkgbW9kdWxlIGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiBjb2xsZWN0UHJvdmlkZXJJbXBvcnRzKHByb2dyYW0sIG5lZ290aWF0aW9uLCByZWNvcmRzLCB1c2VkT3BlcmF0aW9uc0J5TW9kdWxlLCBsYW5ndWFnZSwgb3duZXJNb2R1bGVJZCA9IG51bGwpIHtcbiAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBzdHJpbmdbXT59ICovXG4gIGNvbnN0IHByb3ZpZGVySW1wb3J0c0J5TW9kdWxlID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgcHJvZ3JhbS5tb2R1bGVzKSB7XG4gICAgaWYgKG1vZHVsZS5jYXBhYmlsaXRpZXMgPT09IHVuZGVmaW5lZCkgY29udGludWVcbiAgICBjb25zdCB1c2VkID0gbmV3IFNldCgodXNlZE9wZXJhdGlvbnNCeU1vZHVsZS5nZXQobW9kdWxlLmlkKSA/PyBbXSkubWFwKCh7bW9kdWxlOiBvd25lciwgb3BlcmF0aW9ufSkgPT5cbiAgICAgIHF1YWxpZmllZE9wZXJhdGlvbktleShvd25lciwgb3BlcmF0aW9uKSkpXG4gICAgLyoqIEB0eXBlIHtTZXQ8c3RyaW5nPn0gKi9cbiAgICBjb25zdCBzdXJmYWNlID0gbmV3IFNldCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBzdHJpbmc+fSAqL1xuICAgIGNvbnN0IHJlc291cmNlTmFtZUJ5SWQgPSBuZXcgTWFwKClcblxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgc3RyaW5nPn0gKi9cbiAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWVzID0gbmV3IE1hcCgobW9kdWxlLnJlY29yZHMgPz8gW10pLm1hcCgoZGVjbGFyYXRpb24pID0+IFsvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb24ubmFtZV0pKVxuXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZXJyb3JzID8/IFtdKSB7XG4gICAgICBkZWNsYXJhdGlvbk5hbWVzLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb24ubmFtZSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNhcGFiaWxpdHkgb2YgbW9kdWxlLmNhcGFiaWxpdGllcykge1xuICAgICAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBjYXBhYmlsaXR5LnJlc291cmNlcykge1xuICAgICAgICBzdXJmYWNlLmFkZChyZXNvdXJjZS5uYW1lKVxuICAgICAgICByZXNvdXJjZU5hbWVCeUlkLnNldChyZXNvdXJjZS5pZCwgcmVzb3VyY2UubmFtZSlcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZmFpbHVyZSBvZiBjYXBhYmlsaXR5LmZhaWx1cmVzKSB7XG4gICAgICAgIHN1cmZhY2UuYWRkKGZhaWx1cmUubmFtZSlcbiAgICAgICAgZGVjbGFyYXRpb25OYW1lcy5zZXQoZmFpbHVyZS5pZCwgZmFpbHVyZS5uYW1lKVxuICAgICAgfVxuICAgIH1cbiAgICBjb25zdCByZWZlcmVuY2VkID0gbmV3IFNldCgpXG4gICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKVxuXG4gICAgLyoqXG4gICAgICogVmlzaXRzIG9uZSBzZW1hbnRpYyB2YWx1ZS5cbiAgICAgKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHNlbWFudGljIHN1YnRyZWUuXG4gICAgICogQHJldHVybnMge3ZvaWR9XG4gICAgICovXG4gICAgY29uc3QgdmlzaXQgPSAodmFsdWUpID0+IHtcbiAgICAgIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXModmFsdWUpKSByZXR1cm5cbiAgICAgIHNlZW4uYWRkKHZhbHVlKVxuXG4gICAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpKSB7XG4gICAgICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJraW5kXCIpXG5cbiAgICAgICAgaWYgKGtpbmQgPT0gXCJPd25lZFJlc291cmNlVHlwZVwiKSB7XG4gICAgICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IFJlZmxlY3QuZ2V0KHZhbHVlLCBcInJlc291cmNlSWRcIilcblxuICAgICAgICAgIGlmICh0eXBlb2YgcmVzb3VyY2VJZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gcmVzb3VyY2VOYW1lQnlJZC5nZXQocmVzb3VyY2VJZClcblxuICAgICAgICAgICAgaWYgKG5hbWUgIT09IHVuZGVmaW5lZCkgcmVmZXJlbmNlZC5hZGQobmFtZSlcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSBpZiAoa2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIiB8fCBraW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIgfHwga2luZCA9PSBcIkVycm9yVHlwZVwiKSB7XG4gICAgICAgICAgY29uc3QgZGVjbGFyYXRpb25JZCA9IFJlZmxlY3QuZ2V0KHZhbHVlLCBcImRlY2xhcmF0aW9uSWRcIilcblxuICAgICAgICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb25JZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICBjb25zdCBuYW1lID0gZGVjbGFyYXRpb25OYW1lcy5nZXQoZGVjbGFyYXRpb25JZClcblxuICAgICAgICAgICAgaWYgKG5hbWUgIT09IHVuZGVmaW5lZCAmJiBzdXJmYWNlLmhhcyhuYW1lKSkgcmVmZXJlbmNlZC5hZGQobmFtZSlcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXModmFsdWUpKSB7XG4gICAgICAgICAgaWYgKGtleSA9PSBcImNhcGFiaWxpdGllc1wiIHx8IGtleSA9PSBcImxvY2F0aW9uXCIgfHwga2V5ID09IFwic291cmNlUHJvdmVuYW5jZVwiKSBjb250aW51ZVxuICAgICAgICAgIHZpc2l0KGNoaWxkKVxuICAgICAgICB9XG4gICAgICB9IGVsc2UgZm9yIChjb25zdCBjaGlsZCBvZiB2YWx1ZSkgdmlzaXQoY2hpbGQpXG4gICAgfVxuXG4gICAgdmlzaXQobW9kdWxlKVxuICAgIGNvbnN0IG5hbWVzID0gW11cblxuICAgIGlmIChsYW5ndWFnZSAhPSBcImphdmFcIiB8fCBtb2R1bGUuaWQgIT0gb3duZXJNb2R1bGVJZCkge1xuICAgICAgZm9yIChjb25zdCBjYXBhYmlsaXR5IG9mIG1vZHVsZS5jYXBhYmlsaXRpZXMpIHtcbiAgICAgICAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBjYXBhYmlsaXR5LnJlc291cmNlcykgaWYgKHJlZmVyZW5jZWQuaGFzKHJlc291cmNlLm5hbWUpKSBuYW1lcy5wdXNoKHJlc291cmNlLm5hbWUpXG4gICAgICAgIGZvciAoY29uc3QgZmFpbHVyZSBvZiBjYXBhYmlsaXR5LmZhaWx1cmVzKSBpZiAocmVmZXJlbmNlZC5oYXMoZmFpbHVyZS5uYW1lKSkgbmFtZXMucHVzaChmYWlsdXJlLm5hbWUpXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChsYW5ndWFnZSAhPSBcImphdmFcIikge1xuICAgICAgZm9yIChjb25zdCBwcm92aWRlciBvZiBuZWdvdGlhdGlvbi5wcm92aWRlcnMpIHtcbiAgICAgICAgY29uc3QgcmVjb3JkID0gcmVjb3Jkcy5nZXQocHJvdmlkZXIubW9kdWxlKVxuXG4gICAgICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIHByb3ZpZGVyLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgICBpZiAodXNlZC5oYXMocXVhbGlmaWVkT3BlcmF0aW9uS2V5KHByb3ZpZGVyLm1vZHVsZSwgb3BlcmF0aW9uKSkpIHtcbiAgICAgICAgICAgIG5hbWVzLnB1c2goLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyZWNvcmQ/Lm5hdGl2ZUVudHJpZXNbb3BlcmF0aW9uXSkpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcHJvdmlkZXJJbXBvcnRzQnlNb2R1bGUuc2V0KG1vZHVsZS5pZCwgbmFtZXMpXG4gIH1cbiAgcmV0dXJuIHByb3ZpZGVySW1wb3J0c0J5TW9kdWxlXG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSB0cnV0aGZ1bCBnZW5lcmF0ZWQgc3RkbGliIGxpbmsgbWV0YWRhdGEgZm9yIG9uZSBuZWdvdGlhdGVkIGNsb3N1cmUuXG4gKiBKYXZhIHJlcG9ydHMgdGhlIG93bmVyIG1vZHVsZSBmaWxlIGFzIHRoZSBwcm92aWRlciBjYXJyaWVyIGluc3RlYWQgb2YgYSBzZXBhcmF0ZSBhcnRpZmFjdC5cbiAqIEBwYXJhbSB7U3RkbGliUHJvZ3JhbUxpbmtpbmcgfCBudWxsfSBsaW5raW5nIC0gTGlua2luZyBwbGFuLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBzdHJpbmc+fSBwYXRocyAtIFBsYW5uZWQgYXJ0aWZhY3QgcGF0aCBieSBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0ZGxpYkZhY2FkZVByb2dyYW1EZXNjcmlwdG9yIHwgdW5kZWZpbmVkfSBmYWNhZGVzIC0gU2VsZWN0ZWQgc291cmNlIGZhY2FkZSBjbG9zdXJlLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSBQbGFpbiBKU09OIG1ldGFkYXRhLlxuICovXG5mdW5jdGlvbiBzdGRsaWJMaW5rTWV0YWRhdGEobGlua2luZywgcGF0aHMsIGZhY2FkZXMpIHtcbiAgcmV0dXJuIHtcbiAgICAuLi4oZmFjYWRlcyA/IHtmYWNhZGVzfSA6IHt9KSxcbiAgICBtb2R1bGVzOiAobGlua2luZz8ubmVnb3RpYXRpb24ubW9kdWxlcyA/PyBbXSkubWFwKChpdGVtKSA9PiAoe1xuICAgICAgaWRlbnRpdHk6IGl0ZW0uaWRlbnRpdHksXG4gICAgICBvcGVyYXRpb25zOiBbLi4uaXRlbS5vcGVyYXRpb25zXSxcbiAgICAgIHZlcnNpb246IGl0ZW0udmVyc2lvblxuICAgIH0pKSxcbiAgICBwcm92aWRlcnM6IChsaW5raW5nPy5uZWdvdGlhdGlvbi5wcm92aWRlcnMgPz8gW10pLm1hcCgoaXRlbSkgPT4ge1xuICAgICAgY29uc3QgcmVjb3JkID0gbGlua2luZz8ucmVjb3Jkcy5nZXQoaXRlbS5tb2R1bGUpXG4gICAgICBjb25zdCBhcnRpZmFjdFBhdGggPSBsaW5raW5nPy5vd25lck1vZHVsZUlkICE9PSBudWxsICYmIGxpbmtpbmc/Lm93bmVyTW9kdWxlSWQgIT09IHVuZGVmaW5lZFxuICAgICAgICA/IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocGF0aHMuZ2V0KGxpbmtpbmcub3duZXJNb2R1bGVJZCkpXG4gICAgICAgIDogcmVjb3JkPy5hcnRpZmFjdC5wYXRoXG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGFydGlmYWN0OiB7bWVkaWFUeXBlOiByZWNvcmQ/LmFydGlmYWN0Lm1lZGlhVHlwZSwgcGF0aDogYXJ0aWZhY3RQYXRofSxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiAocmVjb3JkPy5kZXBlbmRlbmNpZXMgPz8gW10pLm1hcCgoZGVwZW5kZW5jeSkgPT4gKHttb2R1bGU6IGRlcGVuZGVuY3kubW9kdWxlLCByYW5nZTogZGVwZW5kZW5jeS5yYW5nZX0pKSxcbiAgICAgICAgaWRlbnRpdHk6IGl0ZW0uaWRlbnRpdHksXG4gICAgICAgIG1vZHVsZTogaXRlbS5tb2R1bGUsXG4gICAgICAgIG5hdGl2ZUVudHJpZXM6IHsuLi5pdGVtLm5hdGl2ZUVudHJpZXN9LFxuICAgICAgICBvcGVyYXRpb25zOiBbLi4uaXRlbS5vcGVyYXRpb25zXSxcbiAgICAgICAgdGFyZ2V0OiBpdGVtLnRhcmdldCxcbiAgICAgICAgdmVyc2lvbjogaXRlbS52ZXJzaW9uXG4gICAgICB9XG4gICAgfSksXG4gICAgc2NoZW1hOiBcIlNlbWFudGlmb2xkU3RkbGliTGlua1wiLFxuICAgIHZlcnNpb246IDFcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBldmVyeSBtYW5kYXRvcnkgc2VtYW50aWMgbG9jYXRpb24gYWdhaW5zdCBpdHMgb3duaW5nIG1vZHVsZSBzb3VyY2UgYmVmb3JlIHdyaXRlciBhbGxvY2F0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IHByb2dyYW0gLSBTdHJ1Y3R1cmFsbHkgYW5kIHNlbWFudGljYWxseSB2YWxpZGF0ZWQgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVQcm9ncmFtU291cmNlT3duZXJzaGlwKHByb2dyYW0sIGxhbmd1YWdlKSB7XG4gIGNvbnN0IHNvdXJjZXMgPSBuZXcgTWFwKHByb2dyYW0uc291cmNlcy5tYXAoKHNvdXJjZSkgPT4gW3NvdXJjZS5maWxlbmFtZSwge1xuICAgIC4uLnNvdXJjZSxcbiAgICBjb29yZGluYXRlczogY3JlYXRlQ29vcmRpbmF0ZUluZGV4KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoc291cmNlLmNvbnRlbnQpKVxuICB9XSkpXG5cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgcHJvZ3JhbS5tb2R1bGVzKSB7XG4gICAgY29uc3Qgc291cmNlID0gc291cmNlcy5nZXQobW9kdWxlLnNvdXJjZUZpbGVuYW1lKVxuXG4gICAgaWYgKCFzb3VyY2UpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJzZW1hbnRpYyBwcm9ncmFtIG1vZHVsZSBzb3VyY2Ugb3duZXJzaGlwXCIsIHVuZGVmaW5lZClcbiAgICBjb25zdCBmYWxsYmFjayA9IG1vZHVsZUxvY2F0aW9uKHNvdXJjZS5maWxlbmFtZSwgLyoqIEB0eXBlIHtzdHJpbmd9ICovIChzb3VyY2UuY29udGVudCkpXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIHNlbWFudGljRW50cmllcyhtb2R1bGUpKSB7XG4gICAgICBjb25zdCBzdWJqZWN0ID0gZW50cnkubm9kZS5raW5kID09IFwiTW9kdWxlXCIgPyBcIm1vZHVsZVwiIDogZW50cnkubm9kZS5raW5kID09IFwiSW1wb3J0XCIgPyBcImltcG9ydFwiIDpcbiAgICAgICAgZW50cnkubm9kZS5raW5kID09IFwiRXhwb3J0XCIgPyBcImV4cG9ydFwiIDogXCJzZW1hbnRpYyBub2RlXCJcblxuICAgICAgaWYgKCEoXCJsb2NhdGlvblwiIGluIGVudHJ5Lm5vZGUpKSB7XG4gICAgICAgIGlmIChzdWJqZWN0ICE9IFwic2VtYW50aWMgbm9kZVwiKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBzZW1hbnRpYyBwcm9ncmFtICR7c3ViamVjdH0gbG9jYXRpb25gLCBmYWxsYmFjaylcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGNvbnN0IGxvY2F0aW9uID0gZW50cnkubm9kZS5sb2NhdGlvblxuXG4gICAgICBpZiAoc291cmNlT3duc0xvY2F0aW9uKHNvdXJjZSwgbG9jYXRpb24pKSBjb250aW51ZVxuXG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBzZW1hbnRpYyBwcm9ncmFtICR7c3ViamVjdH0gbG9jYXRpb24gc291cmNlIG93bmVyc2hpcGAsIGZhbGxiYWNrKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIENoZWNrcyBhIG5vcm1hbGl6ZWQgVVRGLTE2IGxvY2F0aW9uIGFnYWluc3Qgb25lIGV4YWN0IHJlZ2lzdGVyZWQgc291cmNlIHdpdGhvdXQgdGhyb3dpbmcuXG4gKiBAcGFyYW0ge3tmaWxlbmFtZTogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcgfCBudWxsLCBjb29yZGluYXRlczogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlQ29vcmRpbmF0ZUluZGV4Pn19IHNvdXJjZSAtIE93bmluZyBzb3VyY2UuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBzb3VyY2Ugb3ducyB0aGUgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHNvdXJjZU93bnNMb2NhdGlvbihzb3VyY2UsIGNhbmRpZGF0ZSkge1xuICBpZiAoIWlzUGxhaW5PYmplY3QoY2FuZGlkYXRlKSB8fCBjYW5kaWRhdGUuZmlsZW5hbWUgIT0gc291cmNlLmZpbGVuYW1lIHx8ICFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZS5zdGFydCkgfHxcbiAgICAhaXNQbGFpbk9iamVjdChjYW5kaWRhdGUuZW5kKSB8fCAhTnVtYmVyLmlzSW50ZWdlcihjYW5kaWRhdGUuc3RhcnQub2Zmc2V0KSB8fCAhTnVtYmVyLmlzSW50ZWdlcihjYW5kaWRhdGUuZW5kLm9mZnNldCkgfHxcbiAgICAhTnVtYmVyLmlzSW50ZWdlcihjYW5kaWRhdGUuc3RhcnQubGluZSkgfHwgIU51bWJlci5pc0ludGVnZXIoY2FuZGlkYXRlLnN0YXJ0LmNvbHVtbikgfHxcbiAgICAhTnVtYmVyLmlzSW50ZWdlcihjYW5kaWRhdGUuZW5kLmxpbmUpIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKGNhbmRpZGF0ZS5lbmQuY29sdW1uKSkgcmV0dXJuIGZhbHNlXG4gIGNvbnN0IHN0YXJ0T2Zmc2V0ID0gLyoqIEB0eXBlIHtudW1iZXJ9ICovIChjYW5kaWRhdGUuc3RhcnQub2Zmc2V0KVxuICBjb25zdCBlbmRPZmZzZXQgPSAvKiogQHR5cGUge251bWJlcn0gKi8gKGNhbmRpZGF0ZS5lbmQub2Zmc2V0KVxuXG4gIGlmIChzdGFydE9mZnNldCA8IDAgfHwgZW5kT2Zmc2V0IDwgc3RhcnRPZmZzZXQgfHwgZW5kT2Zmc2V0ID4gc291cmNlLmNvb3JkaW5hdGVzLnNvdXJjZS5sZW5ndGgpIHJldHVybiBmYWxzZVxuICBjb25zdCBleHBlY3RlZFN0YXJ0ID0gaW5kZXhlZFBvaW50QXQoc291cmNlLmNvb3JkaW5hdGVzLCBzdGFydE9mZnNldClcbiAgY29uc3QgZXhwZWN0ZWRFbmQgPSBpbmRleGVkUG9pbnRBdChzb3VyY2UuY29vcmRpbmF0ZXMsIGVuZE9mZnNldClcblxuICByZXR1cm4gc2FtZVBvaW50KGNhbmRpZGF0ZS5zdGFydCwgZXhwZWN0ZWRTdGFydCkgJiYgc2FtZVBvaW50KGNhbmRpZGF0ZS5lbmQsIGV4cGVjdGVkRW5kKVxufVxuXG4vKipcbiAqIENvbXBhcmVzIGFuIHVudHJ1c3RlZCBwb2ludCB3aXRoIG9uZSBjYW5vbmljYWwgaW5kZXhlZCBwb2ludC5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBwb2ludC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlUG9pbnR9IGV4cGVjdGVkIC0gQ2Fub25pY2FsIHBvaW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgZXZlcnkgY29vcmRpbmF0ZSBhZ3JlZXMuXG4gKi9cbmZ1bmN0aW9uIHNhbWVQb2ludChjYW5kaWRhdGUsIGV4cGVjdGVkKSB7XG4gIHJldHVybiBjYW5kaWRhdGUub2Zmc2V0ID09IGV4cGVjdGVkLm9mZnNldCAmJiBjYW5kaWRhdGUubGluZSA9PSBleHBlY3RlZC5saW5lICYmIGNhbmRpZGF0ZS5jb2x1bW4gPT0gZXhwZWN0ZWQuY29sdW1uXG59XG5cbi8qKlxuICogQ29sbGVjdHMgbm9taW5hbCBmYWlsdXJlIGlkZW50aXRpZXMgcmVmZXJlbmNlZCBieSBleGVjdXRhYmxlL3R5cGUgbm9kZXMgb3V0c2lkZSB0aGUgbW9kdWxlJ3MgYXV0aG9yaXR5IGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfSBtb2R1bGUgLSBQcm9ncmFtIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtTZXQ8c3RyaW5nPn0gUmVmZXJlbmNlZCBmYWlsdXJlIGRlY2xhcmF0aW9uIGlkZW50aXRpZXMuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3RSZWZlcmVuY2VkRmFpbHVyZUlkcyhtb2R1bGUpIHtcbiAgLyoqIEB0eXBlIHtTZXQ8c3RyaW5nPn0gKi9cbiAgY29uc3QgaWRzID0gbmV3IFNldCgpXG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0KClcbiAgLyoqXG4gICAqIFZpc2l0cyBvbmUgc2VtYW50aWMgc3VidHJlZSBmb3IgcmVmZXJlbmNlZCBmYWlsdXJlcy5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyBzdWJ0cmVlLlxuICAgKi9cbiAgY29uc3QgdmlzaXQgPSAodmFsdWUpID0+IHtcbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuXG4gICAgc2Vlbi5hZGQodmFsdWUpXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgaWYgKFJlZmxlY3QuZ2V0KHZhbHVlLCBcImtpbmRcIikgPT0gXCJFcnJvclR5cGVcIiAmJiB0eXBlb2YgUmVmbGVjdC5nZXQodmFsdWUsIFwiZGVjbGFyYXRpb25JZFwiKSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGlkcy5hZGQoUmVmbGVjdC5nZXQodmFsdWUsIFwiZGVjbGFyYXRpb25JZFwiKSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZhaWx1cmVJZHMgPSBSZWZsZWN0LmdldCh2YWx1ZSwgXCJmYWlsdXJlSWRzXCIpXG5cbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGZhaWx1cmVJZHMpKSBmb3IgKGNvbnN0IGlkIG9mIGZhaWx1cmVJZHMpIGlmICh0eXBlb2YgaWQgPT0gXCJzdHJpbmdcIikgaWRzLmFkZChpZClcbiAgICAgIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgICBpZiAoW1wiY2FwYWJpbGl0aWVzXCIsIFwibG9jYXRpb25cIiwgXCJwcm92ZW5hbmNlXCIsIFwic291cmNlUHJvdmVuYW5jZVwiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgICB2aXNpdChjaGlsZClcbiAgICAgIH1cbiAgICB9IGVsc2UgZm9yIChjb25zdCBjaGlsZCBvZiB2YWx1ZSkgdmlzaXQoY2hpbGQpXG4gIH1cblxuICB2aXNpdCh7Y2xhc3NlczogbW9kdWxlLmNsYXNzZXMsIGVudHJ5UG9pbnQ6IG1vZHVsZS5lbnRyeVBvaW50LCBmdW5jdGlvbnM6IG1vZHVsZS5mdW5jdGlvbnN9KVxuICByZXR1cm4gaWRzXG59XG5cbi8qKlxuICogQ3JlYXRlcyBhbmQgdmFsaWRhdGVzIGV2ZXJ5IGJhY2tlbmQtc2hhcGVkIG1vZHVsZSBiZWZvcmUgYW55IHdyaXRlciBpcyBhbGxvY2F0ZWQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gcHJvZ3JhbSAtIFZhbGlkYXRlZCBzZW1hbnRpYyBwcm9ncmFtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7U3RkbGliUHJvZ3JhbUxpbmtpbmcgfCBudWxsfSBbbGlua2luZ10gLSBQbGFubmVkIHN0ZGxpYiBwcm92aWRlciBsaW5rLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlW119IEVtaXNzaW9uIHZpZXdzIGluIGRlcGVuZGVuY3kgb3JkZXIuXG4gKi9cbmZ1bmN0aW9uIHByZXBhcmVFbWlzc2lvbk1vZHVsZXMocHJvZ3JhbSwgbGFuZ3VhZ2UsIGxpbmtpbmcgPSBudWxsKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSAqL1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBwcm9ncmFtLm1vZHVsZXMpIHtcbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5yZWNvcmRzID8/IFtdKSBkZWNsYXJhdGlvbnMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbilcbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5jbGFzc2VzID8/IFtdKSBkZWNsYXJhdGlvbnMuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbilcbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5lcnJvcnMgPz8gW10pIGRlY2xhcmF0aW9ucy5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGRlY2xhcmF0aW9uKVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykgZGVjbGFyYXRpb25zLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb24pXG4gIH1cbiAgY29uc3QgbW9kdWxlcyA9IHByb2dyYW0ubW9kdWxlcy5tYXAoKG1vZHVsZSkgPT4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gKi8gKHtcbiAgICAuLi5tb2R1bGUsXG4gICAgZW50cnlQb2ludDogbW9kdWxlLmVudHJ5UG9pbnQgPz8ge1xuICAgICAgYm9keToge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLCBsb2NhdGlvbjogbW9kdWxlLmxvY2F0aW9uLCBzdGF0ZW1lbnRzOiBbXX0sXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFbnRyeVBvaW50XCIpLFxuICAgICAgbG9jYXRpb246IG1vZHVsZS5sb2NhdGlvblxuICAgIH1cbiAgfSkpXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgU2V0PHN0cmluZz4+fSAqL1xuICBjb25zdCBjYWxsRWZmZWN0c0J5RGVjbGFyYXRpb25JZCA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIG1vZHVsZXMpIHtcbiAgICBjb25zdCBwcm9ncmFtTW9kdWxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChtb2R1bGUpKVxuICAgIGNvbnN0IHZpc2libGVGdW5jdGlvbnMgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlQ2FsbEVmZmVjdHMgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlUmVjb3JkcyA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IHZpc2libGVDbGFzc2VzID0gbmV3IE1hcCgpXG4gICAgY29uc3QgdmlzaWJsZUVycm9ycyA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IGV4dGVybmFsRGVjbGFyYXRpb25JZHMgPSBuZXcgU2V0KClcblxuICAgIGNvbnN0IG5lZWRlZEZhaWx1cmVJZHMgPSBjb2xsZWN0UmVmZXJlbmNlZEZhaWx1cmVJZHMocHJvZ3JhbU1vZHVsZSlcbiAgICBjb25zdCBsb2NhbEZhaWx1cmVJZHMgPSBuZXcgU2V0KHByb2dyYW1Nb2R1bGUuY2FwYWJpbGl0aWVzPy5mbGF0TWFwKCh7ZmFpbHVyZXN9KSA9PiBmYWlsdXJlcy5tYXAoKHtpZH0pID0+IGlkKSkgPz8gW10pXG5cbiAgICBmb3IgKGNvbnN0IG93bmVyIG9mIHByb2dyYW0ubW9kdWxlcykge1xuICAgICAgaWYgKG93bmVyLmlkID09IHByb2dyYW1Nb2R1bGUuaWQpIGNvbnRpbnVlXG4gICAgICBmb3IgKGNvbnN0IGNhcGFiaWxpdHkgb2Ygb3duZXIuY2FwYWJpbGl0aWVzID8/IFtdKSB7XG4gICAgICAgIGZvciAoY29uc3QgZmFpbHVyZSBvZiBjYXBhYmlsaXR5LmZhaWx1cmVzKSB7XG4gICAgICAgICAgaWYgKCFsb2NhbEZhaWx1cmVJZHMuaGFzKGZhaWx1cmUuaWQpICYmIG5lZWRlZEZhaWx1cmVJZHMuaGFzKGZhaWx1cmUuaWQpKSB2aXNpYmxlRXJyb3JzLnNldChmYWlsdXJlLmlkLCBmYWlsdXJlKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBpbXBvcnRlZCBvZiBwcm9ncmFtTW9kdWxlLmltcG9ydHMpIHtcbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gZGVjbGFyYXRpb25zLmdldChpbXBvcnRlZC5kZWNsYXJhdGlvbklkKVxuXG4gICAgICBpZiAoIWRlY2xhcmF0aW9uKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwicHJvZ3JhbSBpbXBvcnQgd2l0aG91dCBhIGRlY2xhcmF0aW9uXCIsIGltcG9ydGVkLmxvY2F0aW9uKVxuICAgICAgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcy5hZGQoaW1wb3J0ZWQuZGVjbGFyYXRpb25JZClcbiAgICAgIGlmIChpbXBvcnRlZC5zeW1ib2xLaW5kID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB2aXNpYmxlRnVuY3Rpb25zLnNldChpbXBvcnRlZC5sb2NhbE5hbWUsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gKi8gKGRlY2xhcmF0aW9uKSlcbiAgICAgICAgdmlzaWJsZUNhbGxFZmZlY3RzLnNldChpbXBvcnRlZC5sb2NhbE5hbWUsIG5ldyBTZXQoY2FsbEVmZmVjdHNCeURlY2xhcmF0aW9uSWQuZ2V0KGltcG9ydGVkLmRlY2xhcmF0aW9uSWQpID8/IFtdKSlcbiAgICAgIH0gZWxzZSBpZiAoaW1wb3J0ZWQuc3ltYm9sS2luZCA9PSBcInJlY29yZFwiKSB7XG4gICAgICAgIHZpc2libGVSZWNvcmRzLnNldChpbXBvcnRlZC5kZWNsYXJhdGlvbklkLCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9ufSAqLyAoZGVjbGFyYXRpb24pKVxuICAgICAgfSBlbHNlIGlmIChpbXBvcnRlZC5zeW1ib2xLaW5kID09IFwiY2xhc3NcIikge1xuICAgICAgICB2aXNpYmxlQ2xhc3Nlcy5zZXQoaW1wb3J0ZWQuZGVjbGFyYXRpb25JZCwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSAqLyAoZGVjbGFyYXRpb24pKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmlzaWJsZUVycm9ycy5zZXQoaW1wb3J0ZWQuZGVjbGFyYXRpb25JZCwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSAqLyAoZGVjbGFyYXRpb24pKVxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobW9kdWxlLmNhcGFiaWxpdGllcyAhPT0gdW5kZWZpbmVkIHx8ICFsaW5raW5nKSB7XG4gICAgICBwcmVmbGlnaHRFZmZlY3RDYXBhYmlsaXRpZXMobW9kdWxlLCBsYW5ndWFnZSwgbGlua2luZyA/IHt1c2VkT3BlcmF0aW9uczogKGxpbmtpbmcudXNlZE9wZXJhdGlvbnNCeU1vZHVsZS5nZXQocHJvZ3JhbU1vZHVsZS5pZCkgPz8gW10pXG4gICAgICAgIC5tYXAoKHtvcGVyYXRpb259KSA9PiBvcGVyYXRpb24pfSA6IHt9KVxuICAgIH1cbiAgICB2YWxpZGF0ZUJhY2tlbmRNb2R1bGUobW9kdWxlLCBsYW5ndWFnZSwge1xuICAgICAgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcyxcbiAgICAgIHByb2dyYW06IHRydWUsXG4gICAgICB2aXNpYmxlQ2FsbEVmZmVjdHMsXG4gICAgICB2aXNpYmxlQ2xhc3NlcyxcbiAgICAgIHZpc2libGVFcnJvcnMsXG4gICAgICB2aXNpYmxlRnVuY3Rpb25zLFxuICAgICAgdmlzaWJsZVJlY29yZHNcbiAgICB9KVxuICAgIGNvbnN0IGxvY2FsQ2FsbEVmZmVjdHMgPSBtb2R1bGVVbmNoZWNrZWRFcnJvckVmZmVjdHMobW9kdWxlLCB7Y2FsbEVmZmVjdHM6IHZpc2libGVDYWxsRWZmZWN0cywgZnVuY3Rpb25zOiB2aXNpYmxlRnVuY3Rpb25zfSlcblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgICAgY2FsbEVmZmVjdHNCeURlY2xhcmF0aW9uSWQuc2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBuZXcgU2V0KGxvY2FsQ2FsbEVmZmVjdHMuZ2V0KGRlY2xhcmF0aW9uLm5hbWUpID8/IFtdKSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbW9kdWxlc1xufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgY2xvc2VkIHBhcnNlci1uZXV0cmFsIHByb2dyYW0gZ3JhcGggYmVmb3JlIGFueSB0YXJnZXQgZW1pc3Npb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyBwcm9ncmFtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7UmVhZG9ubHk8U2V0PGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2U+Pn0gW3NvdXJjZUxhbmd1YWdlc10gLSBBY2NlcHRlZCBzb3VyY2UgbGFuZ3VhZ2VzLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gVmFsaWRhdGVkIHByb2dyYW0uXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlUHJvZ3JhbShjYW5kaWRhdGUsIGxhbmd1YWdlLCBzb3VyY2VMYW5ndWFnZXMgPSBwcm9ncmFtVGFyZ2V0cykge1xuICBpZiAoIWlzUGxhaW5PYmplY3QoY2FuZGlkYXRlKSB8fCBjYW5kaWRhdGUua2luZCAhPSBcIlByb2dyYW1cIiB8fCB0eXBlb2YgY2FuZGlkYXRlLmVudHJ5TW9kdWxlICE9IFwic3RyaW5nXCIgfHxcbiAgICAhaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5tb2R1bGVzKSB8fCBjYW5kaWRhdGUubW9kdWxlcy5sZW5ndGggPT0gMCB8fCAhaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5zb3VyY2VzKSB8fCBjYW5kaWRhdGUuc291cmNlcy5sZW5ndGggPT0gMCkge1xuICAgIGludmFsaWRQcm9ncmFtR2VuZXJhdGlvbihcIk1hbGZvcm1lZCBzZW1hbnRpYyBwcm9ncmFtLlwiKVxuICB9XG4gIGNvbnN0IHByb2dyYW0gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gKi8gKGNhbmRpZGF0ZSlcbiAgY29uc3QgbW9kdWxlcyA9IG5ldyBNYXAoKVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIHtkZWNsYXJhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24sIG1vZHVsZTogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfT59ICovXG4gIGNvbnN0IGRlY2xhcmF0aW9ucyA9IG5ldyBNYXAoKVxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZVtdfSAqL1xuICBjb25zdCBjYXBhYmlsaXR5TW9kdWxlcyA9IFtdXG4gIGxldCBlbnRyeUNvdW50ID0gMFxuICBjb25zdCBzb3VyY2VJZHMgPSBuZXcgU2V0KClcbiAgY29uc3Qgc291cmNlRmlsZW5hbWVzID0gbmV3IFNldCgpXG5cbiAgZm9yIChjb25zdCBzb3VyY2Ugb2YgcHJvZ3JhbS5zb3VyY2VzKSB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHNvdXJjZSkgfHwgdHlwZW9mIHNvdXJjZS5pZCAhPSBcInN0cmluZ1wiIHx8IHNvdXJjZUlkcy5oYXMoc291cmNlLmlkKSB8fFxuICAgICAgdHlwZW9mIHNvdXJjZS5maWxlbmFtZSAhPSBcInN0cmluZ1wiIHx8ICFpc1NhZmVTb3VyY2VQYXRoKHNvdXJjZS5maWxlbmFtZSkgfHwgc291cmNlRmlsZW5hbWVzLmhhcyhzb3VyY2UuZmlsZW5hbWUpIHx8XG4gICAgICB0eXBlb2Ygc291cmNlLmNvbnRlbnQgIT0gXCJzdHJpbmdcIiB8fCB0eXBlb2Ygc291cmNlLmxhbmd1YWdlICE9IFwic3RyaW5nXCIgfHwgIXNvdXJjZUxhbmd1YWdlcy5oYXMoc291cmNlLmxhbmd1YWdlKSkge1xuICAgICAgaW52YWxpZFByb2dyYW1HZW5lcmF0aW9uKFwiTWFsZm9ybWVkIG9yIGR1cGxpY2F0ZSBzZW1hbnRpYyBwcm9ncmFtIHNvdXJjZSByZWdpc3RyeS5cIilcbiAgICB9XG4gICAgc291cmNlSWRzLmFkZChzb3VyY2UuaWQpXG4gICAgc291cmNlRmlsZW5hbWVzLmFkZChzb3VyY2UuZmlsZW5hbWUpXG4gIH1cblxuICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBwcm9ncmFtLm1vZHVsZXMpIHtcbiAgICBpZiAoIWlzUGxhaW5PYmplY3QobW9kdWxlKSB8fCBtb2R1bGUua2luZCAhPSBcIk1vZHVsZVwiIHx8IHR5cGVvZiBtb2R1bGUuaWQgIT0gXCJzdHJpbmdcIiB8fFxuICAgICAgIS9eW2Etel1bYS16MC05X10qKD86Wy4tXVthLXpdW2EtejAtOV9dKikqJC91LnRlc3QobW9kdWxlLmlkKSB8fCBtb2R1bGVzLmhhcyhtb2R1bGUuaWQpIHx8XG4gICAgICAhaXNEZW5zZUFycmF5KG1vZHVsZS5mdW5jdGlvbnMpIHx8IG1vZHVsZS5yZWNvcmRzICE9PSB1bmRlZmluZWQgJiYgIWlzRGVuc2VBcnJheShtb2R1bGUucmVjb3JkcykgfHxcbiAgICAgIG1vZHVsZS5lcnJvcnMgIT09IHVuZGVmaW5lZCAmJiAhaXNEZW5zZUFycmF5KG1vZHVsZS5lcnJvcnMpIHx8XG4gICAgICAhaXNEZW5zZUFycmF5KG1vZHVsZS5pbXBvcnRzKSB8fCAhaXNEZW5zZUFycmF5KG1vZHVsZS5leHBvcnRzKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBvciBkdXBsaWNhdGUgc2VtYW50aWMgcHJvZ3JhbSBtb2R1bGVcIiwgbW9kdWxlPy5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKFJlZmxlY3QuZ2V0KG1vZHVsZSwgXCJjbGFzc2VzXCIpICE9PSB1bmRlZmluZWQgJiYgKCFpc0RlbnNlQXJyYXkobW9kdWxlLmNsYXNzZXMpIHx8XG4gICAgICBSZWZsZWN0LmdldChtb2R1bGUsIFwic3RkbGliRmFjYWRlXCIpID09PSB1bmRlZmluZWQpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMzMgcmVmZXJlbmNlIGNsYXNzZXMgYXJlIG5vdCBzdXBwb3J0ZWQgYnkgc2VtYW50aWMgcHJvZ3JhbSBnZW5lcmF0aW9uXCIsXG4gICAgICAgIFJlZmxlY3QuZ2V0KG1vZHVsZSwgXCJjbGFzc2VzXCIpPy5bMF0/LmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKFJlZmxlY3QuZ2V0KG1vZHVsZSwgXCJjYXBhYmlsaXRpZXNcIikgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCFpc0RlbnNlQXJyYXkobW9kdWxlLmNhcGFiaWxpdGllcykgfHwgbW9kdWxlLmNhcGFiaWxpdGllcy5sZW5ndGggPT0gMCkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIG9yIGVtcHR5IFRhc2sgMDM0IGNhcGFiaWxpdHkgZ3JhcGhcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY2FwYWJpbGl0eU1vZHVsZXMucHVzaChtb2R1bGUpXG4gICAgfVxuICAgIGlmICh0eXBlb2YgbW9kdWxlLnNvdXJjZUZpbGVuYW1lICE9IFwic3RyaW5nXCIgfHwgIXNvdXJjZUZpbGVuYW1lcy5oYXMobW9kdWxlLnNvdXJjZUZpbGVuYW1lKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInNlbWFudGljIHByb2dyYW0gbW9kdWxlIHNvdXJjZSBpZGVudGl0eVwiLCBtb2R1bGUubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChtb2R1bGUuZW50cnlQb2ludCkge1xuICAgICAgZW50cnlDb3VudCsrXG4gICAgICBpZiAobW9kdWxlLmlkICE9IHByb2dyYW0uZW50cnlNb2R1bGUpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJlbnRyeSBwb2ludCBvbiBhbiB1bnNlbGVjdGVkIG1vZHVsZVwiLCBtb2R1bGUuZW50cnlQb2ludC5sb2NhdGlvbilcbiAgICB9XG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBbLi4ubW9kdWxlLnJlY29yZHMgPz8gW10sIC4uLm1vZHVsZS5jbGFzc2VzID8/IFtdLCAuLi5tb2R1bGUuZXJyb3JzID8/IFtdLCAuLi5tb2R1bGUuZnVuY3Rpb25zXSkge1xuICAgICAgaWYgKCFpc1BsYWluT2JqZWN0KGRlY2xhcmF0aW9uKSB8fCB0eXBlb2YgZGVjbGFyYXRpb24uaWQgIT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICAhZGVjbGFyYXRpb24uaWQuc3RhcnRzV2l0aChgJHttb2R1bGUuaWR9I2ApIHx8IGRlY2xhcmF0aW9ucy5oYXMoZGVjbGFyYXRpb24uaWQpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJkdXBsaWNhdGUgb3IgdW5zdGFibGUgcHJvZ3JhbSBkZWNsYXJhdGlvbiBpZGVudGl0eVwiLCBkZWNsYXJhdGlvbj8ubG9jYXRpb24gPz8gbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgZGVjbGFyYXRpb25zLnNldChkZWNsYXJhdGlvbi5pZCwge2RlY2xhcmF0aW9uLCBtb2R1bGV9KVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGltcG9ydGVkIG9mIG1vZHVsZS5pbXBvcnRzKSB7XG4gICAgICBpZiAoIWlzUGxhaW5PYmplY3QoaW1wb3J0ZWQpIHx8IGltcG9ydGVkLmtpbmQgIT0gXCJJbXBvcnRcIiB8fCB0eXBlb2YgaW1wb3J0ZWQubW9kdWxlSWQgIT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICB0eXBlb2YgaW1wb3J0ZWQuaW1wb3J0ZWROYW1lICE9IFwic3RyaW5nXCIgfHwgdHlwZW9mIGltcG9ydGVkLmxvY2FsTmFtZSAhPSBcInN0cmluZ1wiIHx8XG4gICAgICAgIHR5cGVvZiBpbXBvcnRlZC5kZWNsYXJhdGlvbklkICE9IFwic3RyaW5nXCIgfHwgIVtcImZ1bmN0aW9uXCIsIFwicmVjb3JkXCIsIFwiY2xhc3NcIiwgXCJlcnJvclwiXS5pbmNsdWRlcyhpbXBvcnRlZC5zeW1ib2xLaW5kKSB8fFxuICAgICAgICB0eXBlb2YgaW1wb3J0ZWQudHlwZU9ubHkgIT0gXCJib29sZWFuXCIpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBzZW1hbnRpYyBwcm9ncmFtIGltcG9ydFwiLCBpbXBvcnRlZD8ubG9jYXRpb24gPz8gbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGV4cG9ydGVkIG9mIG1vZHVsZS5leHBvcnRzKSB7XG4gICAgICBpZiAoIWlzUGxhaW5PYmplY3QoZXhwb3J0ZWQpIHx8IGV4cG9ydGVkLmtpbmQgIT0gXCJFeHBvcnRcIiB8fCB0eXBlb2YgZXhwb3J0ZWQuZXhwb3J0ZWROYW1lICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICAgdHlwZW9mIGV4cG9ydGVkLmRlY2xhcmF0aW9uSWQgIT0gXCJzdHJpbmdcIiB8fCAhW1wiZnVuY3Rpb25cIiwgXCJyZWNvcmRcIiwgXCJjbGFzc1wiLCBcImVycm9yXCJdLmluY2x1ZGVzKGV4cG9ydGVkLnN5bWJvbEtpbmQpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgc2VtYW50aWMgcHJvZ3JhbSBleHBvcnRcIiwgZXhwb3J0ZWQ/LmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgbW9kdWxlcy5zZXQobW9kdWxlLmlkLCBtb2R1bGUpXG4gIH1cbiAgaWYgKGVudHJ5Q291bnQgIT0gMSB8fCAhbW9kdWxlcy5nZXQocHJvZ3JhbS5lbnRyeU1vZHVsZSk/LmVudHJ5UG9pbnQpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwicHJvZ3JhbSB3aXRob3V0IGV4YWN0bHkgb25lIHNlbGVjdGVkIGVudHJ5IHBvaW50XCIsIG1vZHVsZXMuZ2V0KHByb2dyYW0uZW50cnlNb2R1bGUpPy5sb2NhdGlvbilcbiAgfVxuICBjb25zdCBzZWxlY3RlZE1vZHVsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfSAqLyAobW9kdWxlcy5nZXQocHJvZ3JhbS5lbnRyeU1vZHVsZSkpXG4gIGNvbnN0IHNlbGVjdGVkRW50cnkgPSBzZWxlY3RlZE1vZHVsZS5lbnRyeVBvaW50XG5cbiAgaWYgKCFpc1BsYWluT2JqZWN0KHNlbGVjdGVkRW50cnk/LmJvZHkpIHx8ICFpc0RlbnNlQXJyYXkoc2VsZWN0ZWRFbnRyeS5ib2R5LnN0YXRlbWVudHMpIHx8IHNlbGVjdGVkRW50cnkuYm9keS5zdGF0ZW1lbnRzLmxlbmd0aCA9PSAwKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInByb2dyYW0gd2l0aG91dCBhIGRlbnNlIG5vbi1lbXB0eSBzZWxlY3RlZCBlbnRyeSBwb2ludCBibG9ja1wiLFxuICAgICAgc2VsZWN0ZWRFbnRyeT8ubG9jYXRpb24gPz8gc2VsZWN0ZWRNb2R1bGUubG9jYXRpb24pXG4gIH1cbiAgY29uc3QgZWFybGllciA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIHByb2dyYW0ubW9kdWxlcykge1xuICAgIGNvbnN0IGxvY2FsVGFyZ2V0TmFtZXMgPSBuZXcgU2V0KFsuLi5tb2R1bGUucmVjb3JkcyA/PyBbXSwgLi4ubW9kdWxlLmNsYXNzZXMgPz8gW10sIC4uLm1vZHVsZS5lcnJvcnMgPz8gW10sIC4uLm1vZHVsZS5mdW5jdGlvbnNdXG4gICAgICAubWFwKCh7bmFtZX0pID0+IHRhcmdldE5hbWUobGFuZ3VhZ2UsIG5hbWUpKSlcbiAgICBjb25zdCBpbXBvcnRlZFRhcmdldE5hbWVzID0gbmV3IFNldCgpXG4gICAgY29uc3QgbG9jYWxKYXZhQ2xhc3MgPSBtb2R1bGUucmVjb3Jkcz8uWzBdPy5uYW1lID8/IG1vZHVsZS5jbGFzc2VzPy5bMF0/Lm5hbWUgPz8gbW9kdWxlLmVycm9ycz8uWzBdPy5uYW1lID8/XG4gICAgICAobW9kdWxlLmlkID09IHByb2dyYW0uZW50cnlNb2R1bGUgPyBcIk1haW5cIiA6IG1vZHVsZUNsYXNzTmFtZShtb2R1bGUuaWQpKVxuICAgIGNvbnN0IGphdmFJbXBvcnRDbGFzc2VzID0gbmV3IE1hcChsYW5ndWFnZSA9PSBcImphdmFcIiA/IFtbbG9jYWxKYXZhQ2xhc3MsIG1vZHVsZS5pZF1dIDogW10pXG5cbiAgICBmb3IgKGNvbnN0IGltcG9ydGVkIG9mIG1vZHVsZS5pbXBvcnRzKSB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IGRlY2xhcmF0aW9ucy5nZXQoaW1wb3J0ZWQuZGVjbGFyYXRpb25JZClcbiAgICAgIGNvbnN0IHJlbW90ZUV4cG9ydCA9IHJlc29sdmVkPy5tb2R1bGUuZXhwb3J0cy5maW5kKChpdGVtKSA9PlxuICAgICAgICBpdGVtLmRlY2xhcmF0aW9uSWQgPT0gaW1wb3J0ZWQuZGVjbGFyYXRpb25JZCAmJiBpdGVtLmV4cG9ydGVkTmFtZSA9PSBpbXBvcnRlZC5pbXBvcnRlZE5hbWUpXG5cbiAgICAgIGlmICghcmVzb2x2ZWQgfHwgcmVzb2x2ZWQubW9kdWxlLmlkICE9IGltcG9ydGVkLm1vZHVsZUlkIHx8ICFlYXJsaWVyLmhhcyhpbXBvcnRlZC5tb2R1bGVJZCkgfHxcbiAgICAgICAgIXJlbW90ZUV4cG9ydCkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwidW5yZXNvbHZlZCwgcHJpdmF0ZSwgY3ljbGljLCBvciBvdXQtb2Ytb3JkZXIgcHJvZ3JhbSBpbXBvcnRcIiwgaW1wb3J0ZWQubG9jYXRpb24gPz8gbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgZGVjbGFyYXRpb25LaW5kID0gcmVzb2x2ZWQuZGVjbGFyYXRpb24ua2luZCA9PSBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiA/IFwiZnVuY3Rpb25cIiA6XG4gICAgICAgIHJlc29sdmVkLmRlY2xhcmF0aW9uLmtpbmQgPT0gXCJSZWNvcmREZWNsYXJhdGlvblwiID8gXCJyZWNvcmRcIiA6XG4gICAgICAgICAgcmVzb2x2ZWQuZGVjbGFyYXRpb24ua2luZCA9PSBcIkNsYXNzRGVjbGFyYXRpb25cIiA/IFwiY2xhc3NcIiA6IFwiZXJyb3JcIlxuXG4gICAgICBpZiAoaW1wb3J0ZWQuc3ltYm9sS2luZCAhPSByZW1vdGVFeHBvcnQuc3ltYm9sS2luZCB8fCBpbXBvcnRlZC5zeW1ib2xLaW5kICE9IGRlY2xhcmF0aW9uS2luZCB8fFxuICAgICAgICBpbXBvcnRlZC50eXBlT25seSAmJiBkZWNsYXJhdGlvbktpbmQgIT0gXCJyZWNvcmRcIiAmJiBkZWNsYXJhdGlvbktpbmQgIT0gXCJjbGFzc1wiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJwcm9ncmFtIGltcG9ydCBkZWNsYXJhdGlvbiBraW5kIG1pc21hdGNoXCIsIGltcG9ydGVkLmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGltcG9ydE5hbWUgPSBwcm9ncmFtSW1wb3J0TmFtZShwcm9ncmFtLCBtb2R1bGUsIGltcG9ydGVkKVxuXG4gICAgICBpZiAobGFuZ3VhZ2UgIT0gXCJydWJ5XCIgJiYgbGFuZ3VhZ2UgIT0gXCJqYXZhXCIpIHtcbiAgICAgICAgaWYgKGltcG9ydGVkLnN5bWJvbEtpbmQgIT0gXCJmdW5jdGlvblwiKSB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyKGxhbmd1YWdlLCBpbXBvcnROYW1lLCBpbXBvcnRlZC5sb2NhdGlvbilcbiAgICAgICAgZWxzZSB2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyKGxhbmd1YWdlLCBpbXBvcnROYW1lLCBcImltcG9ydFwiLCBpbXBvcnRlZC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IG5hbWUgPSB0YXJnZXROYW1lKGxhbmd1YWdlLCBpbXBvcnROYW1lKVxuXG4gICAgICBpZiAobGFuZ3VhZ2UgIT0gXCJydWJ5XCIgJiYgbGFuZ3VhZ2UgIT0gXCJqYXZhXCIgJiYgKGxvY2FsVGFyZ2V0TmFtZXMuaGFzKG5hbWUpIHx8IGltcG9ydGVkVGFyZ2V0TmFtZXMuaGFzKG5hbWUpKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB0YXJnZXQgaW1wb3J0LW5hbWUgY29sbGlzaW9uICcke2ltcG9ydE5hbWV9J2AsIGltcG9ydGVkLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKGxhbmd1YWdlID09IFwiamF2YVwiKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydGVkQ2xhc3MgPSBpbXBvcnRlZC5zeW1ib2xLaW5kID09IFwiZnVuY3Rpb25cIiA/IG1vZHVsZUNsYXNzTmFtZShyZXNvbHZlZC5tb2R1bGUuaWQpIDogcmVzb2x2ZWQuZGVjbGFyYXRpb24ubmFtZVxuICAgICAgICBjb25zdCBleGlzdGluZ093bmVyID0gamF2YUltcG9ydENsYXNzZXMuZ2V0KGltcG9ydGVkQ2xhc3MpXG5cbiAgICAgICAgaWYgKGV4aXN0aW5nT3duZXIgJiYgZXhpc3RpbmdPd25lciAhPSByZXNvbHZlZC5tb2R1bGUuaWQpIHtcbiAgICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB0YXJnZXQgaW1wb3J0LWNsYXNzIGNvbGxpc2lvbiAnJHtpbXBvcnRlZENsYXNzfSdgLCBpbXBvcnRlZC5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICBqYXZhSW1wb3J0Q2xhc3Nlcy5zZXQoaW1wb3J0ZWRDbGFzcywgcmVzb2x2ZWQubW9kdWxlLmlkKVxuICAgICAgfVxuICAgICAgaWYgKGxhbmd1YWdlID09IFwicnVieVwiKSB7XG4gICAgICAgIGNvbnN0IGltcG9ydGVkTW9kdWxlID0gbW9kdWxlQ2xhc3NOYW1lKHJlc29sdmVkLm1vZHVsZS5pZClcblxuICAgICAgICBpZiAobG9jYWxUYXJnZXROYW1lcy5oYXMoaW1wb3J0ZWRNb2R1bGUpKSB7XG4gICAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdGFyZ2V0IGltcG9ydC1tb2R1bGUgY29sbGlzaW9uICcke2ltcG9ydGVkTW9kdWxlfSdgLCBpbXBvcnRlZC5sb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaW1wb3J0ZWRUYXJnZXROYW1lcy5hZGQobmFtZSlcbiAgICB9XG4gICAgY29uc3QgdmFsdWVEZWNsYXJhdGlvbklkcyA9IG5ldyBTZXQobW9kdWxlLmltcG9ydHMuZmlsdGVyKCh7dHlwZU9ubHl9KSA9PiAhdHlwZU9ubHkpLm1hcCgoe2RlY2xhcmF0aW9uSWR9KSA9PiBkZWNsYXJhdGlvbklkKSlcbiAgICBjb25zdCB0eXBlT25seURlY2xhcmF0aW9uSWRzID0gbmV3IFNldChtb2R1bGUuaW1wb3J0c1xuICAgICAgLmZpbHRlcigoe2RlY2xhcmF0aW9uSWQsIHR5cGVPbmx5fSkgPT4gdHlwZU9ubHkgJiYgIXZhbHVlRGVjbGFyYXRpb25JZHMuaGFzKGRlY2xhcmF0aW9uSWQpKVxuICAgICAgLm1hcCgoe2RlY2xhcmF0aW9uSWR9KSA9PiBkZWNsYXJhdGlvbklkKSlcbiAgICBjb25zdCB2YWx1ZUNvbnN0cnVjdGlvbiA9IGZpbmRUeXBlT25seVZhbHVlQ29uc3RydWN0aW9uKG1vZHVsZSwgdHlwZU9ubHlEZWNsYXJhdGlvbklkcylcblxuICAgIGlmICh2YWx1ZUNvbnN0cnVjdGlvbikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInR5cGUtb25seSBwcm9ncmFtIGltcG9ydCB1c2VkIGFzIGEgdmFsdWVcIiwgdmFsdWVDb25zdHJ1Y3Rpb24ubG9jYXRpb24gPz8gbW9kdWxlLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBleHBvcnROYW1lcyA9IG5ldyBTZXQoKVxuXG4gICAgZm9yIChjb25zdCBleHBvcnRlZCBvZiBtb2R1bGUuZXhwb3J0cykge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSBkZWNsYXJhdGlvbnMuZ2V0KGV4cG9ydGVkLmRlY2xhcmF0aW9uSWQpXG4gICAgICBjb25zdCBuYW1lID0gdGFyZ2V0TmFtZShsYW5ndWFnZSwgZXhwb3J0ZWQuZXhwb3J0ZWROYW1lKVxuXG4gICAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIpIHtcbiAgICAgICAgdmFsaWRhdGVUYXJnZXRJZGVudGlmaWVyKGxhbmd1YWdlLCBleHBvcnRlZC5leHBvcnRlZE5hbWUsIFwiZXhwb3J0XCIsIGV4cG9ydGVkLmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cblxuICAgICAgaWYgKCFyZXNvbHZlZCB8fCByZXNvbHZlZC5tb2R1bGUuaWQgIT0gbW9kdWxlLmlkIHx8IGV4cG9ydE5hbWVzLmhhcyhuYW1lKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB1bnJlc29sdmVkIG9yIGNvbGxpZGluZyB0YXJnZXQgZXhwb3J0ICcke2V4cG9ydGVkLmV4cG9ydGVkTmFtZX0nYCwgZXhwb3J0ZWQubG9jYXRpb24gPz8gbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgZGVjbGFyYXRpb25LaW5kID0gcmVzb2x2ZWQuZGVjbGFyYXRpb24ua2luZCA9PSBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiA/IFwiZnVuY3Rpb25cIiA6XG4gICAgICAgIHJlc29sdmVkLmRlY2xhcmF0aW9uLmtpbmQgPT0gXCJSZWNvcmREZWNsYXJhdGlvblwiID8gXCJyZWNvcmRcIiA6XG4gICAgICAgICAgcmVzb2x2ZWQuZGVjbGFyYXRpb24ua2luZCA9PSBcIkNsYXNzRGVjbGFyYXRpb25cIiA/IFwiY2xhc3NcIiA6IFwiZXJyb3JcIlxuXG4gICAgICBpZiAoZXhwb3J0ZWQuc3ltYm9sS2luZCAhPSBkZWNsYXJhdGlvbktpbmQpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInByb2dyYW0gZXhwb3J0IGRlY2xhcmF0aW9uIGtpbmQgbWlzbWF0Y2hcIiwgZXhwb3J0ZWQubG9jYXRpb24gPz8gbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKGxhbmd1YWdlICE9IFwiamF2YXNjcmlwdFwiICYmIGxhbmd1YWdlICE9IFwidHlwZXNjcmlwdFwiICYmIGV4cG9ydGVkLmV4cG9ydGVkTmFtZSAhPSByZXNvbHZlZC5kZWNsYXJhdGlvbi5uYW1lKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGV4cG9ydCBhbGlhcyAnJHtleHBvcnRlZC5leHBvcnRlZE5hbWV9JyB3aXRob3V0IGFuIGVxdWl2YWxlbnQgdGFyZ2V0IGJpbmRpbmdgLFxuICAgICAgICAgIGV4cG9ydGVkLmxvY2F0aW9uID8/IHJlc29sdmVkLmRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgZXhwb3J0TmFtZXMuYWRkKG5hbWUpXG4gICAgfVxuICAgIGlmIChsYW5ndWFnZSA9PSBcInBocFwiKSB7XG4gICAgICBjb25zdCBleHBvcnRlZERlY2xhcmF0aW9uSWRzID0gbmV3IFNldChtb2R1bGUuZXhwb3J0cy5tYXAoKHtkZWNsYXJhdGlvbklkfSkgPT4gZGVjbGFyYXRpb25JZCkpXG4gICAgICBjb25zdCBwcml2YXRlRGVjbGFyYXRpb24gPSBbLi4ubW9kdWxlLnJlY29yZHMgPz8gW10sIC4uLm1vZHVsZS5jbGFzc2VzID8/IFtdLCAuLi5tb2R1bGUuZXJyb3JzID8/IFtdLCAuLi5tb2R1bGUuZnVuY3Rpb25zXS5maW5kKCh7aWR9KSA9PlxuICAgICAgICB0eXBlb2YgaWQgPT0gXCJzdHJpbmdcIiAmJiAhZXhwb3J0ZWREZWNsYXJhdGlvbklkcy5oYXMoaWQpKVxuXG4gICAgICBpZiAocHJpdmF0ZURlY2xhcmF0aW9uKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYG5vbi1leHBvcnRlZCBkZWNsYXJhdGlvbiAnJHtwcml2YXRlRGVjbGFyYXRpb24ubmFtZX0nIHdpdGhvdXQgdGFyZ2V0LXByaXZhdGUgbW9kdWxlIHZpc2liaWxpdHlgLFxuICAgICAgICAgIHByaXZhdGVEZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgZWFybGllci5hZGQobW9kdWxlLmlkKVxuICB9XG5cbiAgdmFsaWRhdGVQcm9ncmFtU3RkbGliQ29udHJhY3QocHJvZ3JhbSwgbGFuZ3VhZ2UsIGNhcGFiaWxpdHlNb2R1bGVzKVxuICB2YWxpZGF0ZVByb2dyYW1TdGRsaWJGYWNhZGVzKHByb2dyYW0sIGxhbmd1YWdlKVxuXG4gIHJldHVybiBwcm9ncmFtXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGNvbXBpbGVyLXNlbGVjdGVkIGZhY2FkZSBkZXNjcmlwdG9ycywgZXhlY3V0YWJsZSBzb3VyY2VzLCBtb2R1bGUgbWFya2VycywgYW5kIG5hdGl2ZSBpZGVudGl0eSBldmlkZW5jZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gQ2FuZGlkYXRlIHByb2dyYW0uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlIGZvciBkaWFnbm9zdGljcy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVByb2dyYW1TdGRsaWJGYWNhZGVzKHByb2dyYW0sIGxhbmd1YWdlKSB7XG4gIGNvbnN0IGRlc2NyaXB0b3IgPSBSZWZsZWN0LmdldChwcm9ncmFtLCBcInN0ZGxpYkZhY2FkZXNcIilcbiAgY29uc3QgbWFya2VkTW9kdWxlcyA9IHByb2dyYW0ubW9kdWxlcy5maWx0ZXIoKG1vZHVsZSkgPT4gUmVmbGVjdC5nZXQobW9kdWxlLCBcInN0ZGxpYkZhY2FkZVwiKSAhPT0gdW5kZWZpbmVkKVxuICBjb25zdCBmYWNhZGVTb3VyY2VzID0gcHJvZ3JhbS5zb3VyY2VzLmZpbHRlcigoc291cmNlKSA9PiBSZWZsZWN0LmdldChzb3VyY2UsIFwib3duZXJzaGlwXCIpID09IFwiZmFjYWRlXCIpXG4gIGNvbnN0IGV2aWRlbmNlZEltcG9ydHMgPSBwcm9ncmFtLm1vZHVsZXMuZmxhdE1hcCgobW9kdWxlKSA9PiBtb2R1bGUuaW1wb3J0cy5maWx0ZXIoKGl0ZW0pID0+IFJlZmxlY3QuZ2V0KGl0ZW0sIFwic3RkbGliRmFjYWRlXCIpICE9PSB1bmRlZmluZWQpKVxuXG4gIGlmIChkZXNjcmlwdG9yID09PSB1bmRlZmluZWQpIHtcbiAgICBpZiAobWFya2VkTW9kdWxlcy5sZW5ndGggPiAwIHx8IGZhY2FkZVNvdXJjZXMubGVuZ3RoID4gMCB8fCBldmlkZW5jZWRJbXBvcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBcIkZhY2FkZSBtb2R1bGVzLCBzb3VyY2VzLCBvciBpbXBvcnQgZXZpZGVuY2UgcmVxdWlyZSBhIGNvbXBsZXRlIHByb2dyYW0gZmFjYWRlIGRlc2NyaXB0b3IuXCIpXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmICghaXNQbGFpbk9iamVjdChkZXNjcmlwdG9yKSB8fCBkZXNjcmlwdG9yLnNjaGVtYSAhPSBcIlNlbWFudGlmb2xkU3RkbGliRmFjYWRlc1wiIHx8IGRlc2NyaXB0b3IudmVyc2lvbiAhPSAxIHx8XG4gICAgdHlwZW9mIGRlc2NyaXB0b3IubGFuZ3VhZ2UgIT0gXCJzdHJpbmdcIiB8fCAhcHJvZ3JhbVRhcmdldHMuaGFzKGRlc2NyaXB0b3IubGFuZ3VhZ2UpIHx8ICFpc0RlbnNlQXJyYXkoZGVzY3JpcHRvci5tb2R1bGVzKSB8fFxuICAgIGRlc2NyaXB0b3IubW9kdWxlcy5sZW5ndGggPT0gMCkge1xuICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBcIlRoZSBwcm9ncmFtIGZhY2FkZSBkZXNjcmlwdG9yIGlzIG1hbGZvcm1lZC5cIilcbiAgfVxuICBjb25zdCBmYWNhZGVMYW5ndWFnZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gKi8gKGRlc2NyaXB0b3IubGFuZ3VhZ2UpXG4gIGNvbnN0IHJlY29yZHMgPSBkZXNjcmlwdG9yLm1vZHVsZXMubWFwKChpdGVtKSA9PiB7XG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KGl0ZW0pIHx8IHR5cGVvZiBpdGVtLmlkZW50aXR5ICE9IFwic3RyaW5nXCIgfHwgdHlwZW9mIGl0ZW0udmVyc2lvbiAhPSBcInN0cmluZ1wiKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJUaGUgcHJvZ3JhbSBmYWNhZGUgbW9kdWxlIGRlc2NyaXB0b3IgaXMgbWFsZm9ybWVkLlwiKVxuICAgIH1cbiAgICByZXR1cm4gc3RkbGliRmFjYWRlUmVnaXN0cnkucmVzb2x2ZUlkZW50aXR5KGl0ZW0uaWRlbnRpdHksIGZhY2FkZUxhbmd1YWdlLCBpdGVtLnZlcnNpb24pXG4gIH0pXG4gIGNvbnN0IGV4cGVjdGVkID0gc3RkbGliRmFjYWRlUHJvZ3JhbURlc2NyaXB0b3IoZmFjYWRlTGFuZ3VhZ2UsIHJlY29yZHMpXG5cbiAgaWYgKCFlcXVhbFBsYWluRGF0YShkZXNjcmlwdG9yLCBleHBlY3RlZCkpIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJUaGUgcHJvZ3JhbSBmYWNhZGUgZGVzY3JpcHRvciBkb2VzIG5vdCBtYXRjaCB0aGUgcmVnaXN0ZXJlZCB2ZXJzaW9uZWQgZmFjYWRlIGNsb3N1cmUuXCIpXG4gIH1cbiAgY29uc3Qgc2VsZWN0ZWRSZWNvcmRzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCByZWNvcmQgb2YgcmVjb3Jkcykge1xuICAgIGlmIChzZWxlY3RlZFJlY29yZHMuaGFzKHJlY29yZC5pZGVudGl0eSkpIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBgRmFjYWRlICcke3JlY29yZC5pZGVudGl0eX0nIGlzIHNlbGVjdGVkIG1vcmUgdGhhbiBvbmNlLmApXG4gICAgfVxuICAgIGZvciAoY29uc3QgZGVwZW5kZW5jeSBvZiByZWNvcmQuZGVwZW5kZW5jaWVzKSB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IHN0ZGxpYkZhY2FkZVJlZ2lzdHJ5LnJlc29sdmVJZGVudGl0eShkZXBlbmRlbmN5LmlkZW50aXR5LCBmYWNhZGVMYW5ndWFnZSwgZGVwZW5kZW5jeS5yYW5nZSlcbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gc2VsZWN0ZWRSZWNvcmRzLmdldChyZXNvbHZlZC5pZGVudGl0eSlcblxuICAgICAgaWYgKCFzZWxlY3RlZCB8fCBzZWxlY3RlZC52ZXJzaW9uICE9IHJlc29sdmVkLnZlcnNpb24pIHtcbiAgICAgICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIGBGYWNhZGUgJyR7cmVjb3JkLmlkZW50aXR5fScgZGVwZW5kZW5jeSAnJHtyZXNvbHZlZC5pZGVudGl0eX1AJHtyZXNvbHZlZC52ZXJzaW9ufScgaXMgbWlzc2luZyBvciBvdXQgb2Ygb3JkZXIuYClcbiAgICAgIH1cbiAgICB9XG4gICAgc2VsZWN0ZWRSZWNvcmRzLnNldChyZWNvcmQuaWRlbnRpdHksIHJlY29yZClcbiAgfVxuICBpZiAobWFya2VkTW9kdWxlcy5sZW5ndGggIT0gcmVjb3Jkcy5sZW5ndGgpIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJUaGUgcHJvZ3JhbSBmYWNhZGUgZGVzY3JpcHRvciBkb2VzIG5vdCBtYXRjaCBpdHMgZXhlY3V0YWJsZSBzZW1hbnRpYyBtb2R1bGVzLlwiKVxuICB9XG4gIGlmIChwcm9ncmFtLnNvdXJjZXMuc29tZSgoc291cmNlKSA9PiBzb3VyY2UubGFuZ3VhZ2UgIT0gZmFjYWRlTGFuZ3VhZ2UgfHxcbiAgICAhW1wiYXBwbGljYXRpb25cIiwgXCJmYWNhZGVcIl0uaW5jbHVkZXMoU3RyaW5nKFJlZmxlY3QuZ2V0KHNvdXJjZSwgXCJvd25lcnNoaXBcIikpKSkpIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJGYWNhZGUgcHJvZ3JhbXMgcmVxdWlyZSBvbmUgc291cmNlIGxhbmd1YWdlIGFuZCBleHBsaWNpdCBhcHBsaWNhdGlvbi9mYWNhZGUgb3duZXJzaGlwLlwiKVxuICB9XG4gIGNvbnN0IHNlbGVjdGVkSWRlbnRpdGllcyA9IG5ldyBTZXQocmVjb3Jkcy5tYXAoKHtpZGVudGl0eX0pID0+IGlkZW50aXR5KSlcbiAgY29uc3QgcmVnaXN0ZXJlZE1vZHVsZXMgPSByZXBhcnNlUmVnaXN0ZXJlZEZhY2FkZU1vZHVsZXMocHJvZ3JhbSwgZmFjYWRlTGFuZ3VhZ2UsIGxhbmd1YWdlKVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCByZWNvcmRzLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIGNvbnN0IHJlY29yZCA9IHJlY29yZHNbaW5kZXhdXG4gICAgY29uc3QgbW9kdWxlID0gbWFya2VkTW9kdWxlc1tpbmRleF1cbiAgICBjb25zdCBtYXJrZXIgPSBSZWZsZWN0LmdldChtb2R1bGUsIFwic3RkbGliRmFjYWRlXCIpXG5cbiAgICBpZiAoIWlzUGxhaW5PYmplY3QobWFya2VyKSB8fCBPYmplY3Qua2V5cyhtYXJrZXIpLnNvcnQoKS5qb2luKFwiLFwiKSAhPSBcImlkZW50aXR5LHZlcnNpb25cIiB8fFxuICAgICAgbWFya2VyLmlkZW50aXR5ICE9IHJlY29yZC5pZGVudGl0eSB8fCBtYXJrZXIudmVyc2lvbiAhPSByZWNvcmQudmVyc2lvbiB8fCBtb2R1bGUuaWQgIT0gcmVjb3JkLnNvdXJjZS5pZCB8fFxuICAgICAgbW9kdWxlLnNvdXJjZUZpbGVuYW1lICE9IHJlY29yZC5zb3VyY2UuZmlsZW5hbWUpIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBgRmFjYWRlICcke3JlY29yZC5pZGVudGl0eX0nIHNlbWFudGljIG1vZHVsZSBpZGVudGl0eSBpcyBub3QgY2Fub25pY2FsLmApXG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZSA9IHByb2dyYW0uc291cmNlcy5maW5kKCh7ZmlsZW5hbWV9KSA9PiBmaWxlbmFtZSA9PSByZWNvcmQuc291cmNlLmZpbGVuYW1lKVxuXG4gICAgaWYgKCFzb3VyY2UgfHwgc291cmNlLmNvbnRlbnQgIT0gcmVjb3JkLnNvdXJjZS5jb250ZW50IHx8IFJlZmxlY3QuZ2V0KHNvdXJjZSwgXCJvd25lcnNoaXBcIikgIT0gXCJmYWNhZGVcIikge1xuICAgICAgaW52YWxpZEZhY2FkZURlc2NyaXB0b3IobGFuZ3VhZ2UsIGBGYWNhZGUgJyR7cmVjb3JkLmlkZW50aXR5fScgZXhlY3V0YWJsZSBzb3VyY2UgZG9lcyBub3QgbWF0Y2ggaXRzIHJlZ2lzdGVyZWQgZGVmaW5pdGlvbi5gKVxuICAgIH1cbiAgICBjb25zdCByZWdpc3RlcmVkTW9kdWxlID0gcmVnaXN0ZXJlZE1vZHVsZXMuZ2V0KHJlY29yZC5pZGVudGl0eSlcblxuICAgIGlmICghcmVnaXN0ZXJlZE1vZHVsZSB8fCAhZXF1YWxQbGFpbkRhdGEobW9kdWxlLCByZWdpc3RlcmVkTW9kdWxlKSkge1xuICAgICAgaW52YWxpZEZhY2FkZUF1dGhvcml0eShsYW5ndWFnZSxcbiAgICAgICAgYEZhY2FkZSAnJHtyZWNvcmQuaWRlbnRpdHl9JyBzZW1hbnRpYyBtb2R1bGUgZG9lcyBub3QgbWF0Y2ggaXRzIHJlZ2lzdGVyZWQgZXhlY3V0YWJsZSBzb3VyY2UuYCwgbW9kdWxlLmxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBhbGxvd2VkT3BlcmF0aW9ucyA9IG5ldyBTZXQocmVjb3JkLnJlcXVpcmVtZW50cy5mbGF0TWFwKCh7b3BlcmF0aW9uc30pID0+IG9wZXJhdGlvbnMpKVxuICAgIGNvbnN0IHVzZWRPcGVyYXRpb25zID0gY29sbGVjdERlY2xhcmVkRWZmZWN0T3BlcmF0aW9ucyhtb2R1bGUpXG5cbiAgICBpZiAoYWxsb3dlZE9wZXJhdGlvbnMuc2l6ZSAhPSB1c2VkT3BlcmF0aW9ucy5zaXplIHx8IFsuLi5hbGxvd2VkT3BlcmF0aW9uc10uc29tZSgob3BlcmF0aW9uKSA9PiAhdXNlZE9wZXJhdGlvbnMuaGFzKG9wZXJhdGlvbikpKSB7XG4gICAgICBpbnZhbGlkRmFjYWRlQXV0aG9yaXR5KGxhbmd1YWdlLCBgRmFjYWRlICcke3JlY29yZC5pZGVudGl0eX0nIHNlbWFudGljIGJvZHkgZG9lcyBub3QgbWF0Y2ggaXRzIGRlY2xhcmVkIGNhbm9uaWNhbCByZXF1aXJlbWVudHMuYCwgbW9kdWxlLmxvY2F0aW9uKVxuICAgIH1cbiAgfVxuICBpZiAoZmFjYWRlU291cmNlcy5sZW5ndGggIT0gcmVjb3Jkcy5sZW5ndGgpIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJUaGUgcHJvZ3JhbSBjb250YWlucyBhbiB1bnNlbGVjdGVkIGNvbXBpbGVyLW93bmVkIGZhY2FkZSBzb3VyY2UuXCIpXG4gIH1cbiAgaWYgKGV2aWRlbmNlZEltcG9ydHMubGVuZ3RoID09IDApIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgXCJUaGUgc2VsZWN0ZWQgZmFjYWRlIGNsb3N1cmUgaGFzIG5vIHBhcnNlci1wcm92ZWQgbmF0aXZlIGltcG9ydCBldmlkZW5jZS5cIilcbiAgfVxuICBmb3IgKGNvbnN0IGltcG9ydGVkIG9mIGV2aWRlbmNlZEltcG9ydHMpIHtcbiAgICBjb25zdCBldmlkZW5jZSA9IFJlZmxlY3QuZ2V0KGltcG9ydGVkLCBcInN0ZGxpYkZhY2FkZVwiKVxuXG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KGV2aWRlbmNlKSB8fCBPYmplY3Qua2V5cyhldmlkZW5jZSkuc29ydCgpLmpvaW4oXCIsXCIpICE9XG4gICAgICBcImZhY2FkZUlkZW50aXR5LGZhY2FkZVZlcnNpb24sbmF0aXZlTW9kdWxlLG5hdGl2ZVN5bWJvbCxzY2hlbWEsdmVyc2lvblwiIHx8XG4gICAgICBldmlkZW5jZS5zY2hlbWEgIT0gXCJTZW1hbnRpZm9sZFN0ZGxpYkZhY2FkZVJlc29sdXRpb25cIiB8fCBldmlkZW5jZS52ZXJzaW9uICE9IDEgfHxcbiAgICAgIHR5cGVvZiBldmlkZW5jZS5mYWNhZGVJZGVudGl0eSAhPSBcInN0cmluZ1wiIHx8IHR5cGVvZiBldmlkZW5jZS5mYWNhZGVWZXJzaW9uICE9IFwic3RyaW5nXCIgfHxcbiAgICAgIHR5cGVvZiBldmlkZW5jZS5uYXRpdmVNb2R1bGUgIT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgZXZpZGVuY2UubmF0aXZlU3ltYm9sICE9IFwic3RyaW5nXCIpIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBcIkEgZmFjYWRlIGltcG9ydCBoYXMgbWFsZm9ybWVkIG5hdGl2ZSBpZGVudGl0eSBldmlkZW5jZS5cIilcbiAgICB9XG4gICAgY29uc3QgcmVjb3JkID0gc3RkbGliRmFjYWRlUmVnaXN0cnkucmVzb2x2ZUZhY2FkZShmYWNhZGVMYW5ndWFnZSwgZXZpZGVuY2UubmF0aXZlTW9kdWxlLCBldmlkZW5jZS5uYXRpdmVTeW1ib2wsXG4gICAgICBldmlkZW5jZS5mYWNhZGVWZXJzaW9uKVxuXG4gICAgaWYgKHJlY29yZC5pZGVudGl0eSAhPSBldmlkZW5jZS5mYWNhZGVJZGVudGl0eSB8fCAhc2VsZWN0ZWRJZGVudGl0aWVzLmhhcyhyZWNvcmQuaWRlbnRpdHkpIHx8IGltcG9ydGVkLm1vZHVsZUlkICE9IHJlY29yZC5zb3VyY2UuaWQgfHxcbiAgICAgIGltcG9ydGVkLmltcG9ydGVkTmFtZSAhPSBldmlkZW5jZS5uYXRpdmVTeW1ib2wpIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGxhbmd1YWdlLCBcIkEgZmFjYWRlIGltcG9ydCBkb2VzIG5vdCBtYXRjaCBpdHMgcmVnaXN0ZXJlZCBuYXRpdmUgbW9kdWxlIGFuZCBzeW1ib2wgaWRlbnRpdHkuXCIpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQ29sbGVjdHMgZXZlcnkgY2Fub25pY2FsIG9wZXJhdGlvbiBwcmVzZW50IGluIG9uZSB2YWxpZGF0ZWQgZmFjYWRlIGltcGxlbWVudGF0aW9uLlxuICogVGhpcyBjaGVja3MgdGhlIGZhY2FkZSdzIGNvbXBsZXRlIGRlY2xhcmVkIGF1dGhvcml0eSBpbmRlcGVuZGVudGx5IGZyb20gcHJvZ3JhbSByZWFjaGFiaWxpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gbW9kdWxlIC0gRmFjYWRlIG1vZHVsZS5cbiAqIEByZXR1cm5zIHtTZXQ8c3RyaW5nPn0gVXNlZCBvcGVyYXRpb24gbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3REZWNsYXJlZEVmZmVjdE9wZXJhdGlvbnMobW9kdWxlKSB7XG4gIGNvbnN0IG9wZXJhdGlvbk5hbWVzID0gbmV3IE1hcChtb2R1bGUuY2FwYWJpbGl0aWVzPy5mbGF0TWFwKCh7b3BlcmF0aW9uc30pID0+XG4gICAgb3BlcmF0aW9ucy5tYXAoKG9wZXJhdGlvbikgPT4gW29wZXJhdGlvbi5pZCwgb3BlcmF0aW9uLm5hbWVdKSkgPz8gW10pXG4gIGNvbnN0IHVzZWQgPSBuZXcgU2V0KClcbiAgY29uc3Qgc2VlbiA9IG5ldyBTZXQoKVxuICAvKipcbiAgICogVmlzaXRzIG9uZSBmYWNhZGUgc2VtYW50aWMgc3VidHJlZS5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBzZW1hbnRpYyBzdWJ0cmVlLlxuICAgKi9cbiAgY29uc3QgdmlzaXQgPSAodmFsdWUpID0+IHtcbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuXG4gICAgc2Vlbi5hZGQodmFsdWUpXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgY29uc3Qgb3BlcmF0aW9uID0gUmVmbGVjdC5nZXQodmFsdWUsIFwia2luZFwiKSA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgPyBSZWZsZWN0LmdldCh2YWx1ZSwgXCJvcGVyYXRpb25cIikgOiB1bmRlZmluZWRcblxuICAgICAgaWYgKHR5cGVvZiBvcGVyYXRpb24gPT0gXCJzdHJpbmdcIiAmJiBvcGVyYXRpb25OYW1lcy5oYXMob3BlcmF0aW9uKSkgdXNlZC5hZGQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChvcGVyYXRpb25OYW1lcy5nZXQob3BlcmF0aW9uKSkpXG4gICAgICBmb3IgKGNvbnN0IFtrZXksIGNoaWxkXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcbiAgICAgICAgaWYgKFtcImNhcGFiaWxpdGllc1wiLCBcImxvY2F0aW9uXCIsIFwicHJvdmVuYW5jZVwiLCBcInJlc29sdXRpb25cIiwgXCJzb3VyY2VQcm92ZW5hbmNlXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICAgIHZpc2l0KGNoaWxkKVxuICAgICAgfVxuICAgIH0gZWxzZSBmb3IgKGNvbnN0IGNoaWxkIG9mIHZhbHVlKSB2aXNpdChjaGlsZClcbiAgfVxuXG4gIHZpc2l0KHtjbGFzc2VzOiBtb2R1bGUuY2xhc3NlcywgZW50cnlQb2ludDogbW9kdWxlLmVudHJ5UG9pbnQsIGZ1bmN0aW9uczogbW9kdWxlLmZ1bmN0aW9uc30pXG4gIHJldHVybiB1c2VkXG59XG5cbi8qKlxuICogUmVjb21waWxlcyB0aGUgcmVnaXN0cnktc2VsZWN0ZWQgZmFjYWRlIGNsb3N1cmUgZnJvbSByZXRhaW5lZCBjYWxsZXIgaW5wdXRzIGFuZCByZWdpc3RlcmVkIGZhY2FkZSBzb3VyY2UuXG4gKiBUaGlzIHBhcnNlci1iYWNrZWQgcmVmZXJlbmNlIGdyYXBoIGlzIGNyZWF0ZWQgZHVyaW5nIHZhbGlkYXRpb24sIGJlZm9yZSBwcm92aWRlciBwbGFubmluZyBvciB3cml0ZXIgYWxsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gVW50cnVzdGVkIG11dGFibGUgc2VtYW50aWMgcHJvZ3JhbS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gZmFjYWRlTGFuZ3VhZ2UgLSBTZWxlY3RlZCBzb3VyY2UtbGFuZ3VhZ2UgZmFjYWRlIHByb2ZpbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGRpYWdub3N0aWNMYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZSBmb3IgYm91bmRhcnkgZGlhZ25vc3RpY3MuXG4gKiBAcmV0dXJucyB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlPn0gQ2Fub25pY2FsIHNlbWFudGljIG1vZHVsZXMgYnkgZmFjYWRlIGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiByZXBhcnNlUmVnaXN0ZXJlZEZhY2FkZU1vZHVsZXMocHJvZ3JhbSwgZmFjYWRlTGFuZ3VhZ2UsIGRpYWdub3N0aWNMYW5ndWFnZSkge1xuICBjb25zdCBhcHBsaWNhdGlvbk1vZHVsZXMgPSBwcm9ncmFtLm1vZHVsZXMuZmlsdGVyKChtb2R1bGUpID0+IFJlZmxlY3QuZ2V0KG1vZHVsZSwgXCJzdGRsaWJGYWNhZGVcIikgPT09IHVuZGVmaW5lZClcbiAgY29uc3QgbW9kdWxlc0J5RmlsZW5hbWUgPSBuZXcgTWFwKGFwcGxpY2F0aW9uTW9kdWxlcy5tYXAoKG1vZHVsZSkgPT4gW21vZHVsZS5zb3VyY2VGaWxlbmFtZSwgbW9kdWxlXSkpXG4gIGNvbnN0IGFwcGxpY2F0aW9uU291cmNlcyA9IHByb2dyYW0uc291cmNlcy5maWx0ZXIoKHNvdXJjZSkgPT4gUmVmbGVjdC5nZXQoc291cmNlLCBcIm93bmVyc2hpcFwiKSA9PSBcImFwcGxpY2F0aW9uXCIpLm1hcCgoc291cmNlKSA9PiB7XG4gICAgY29uc3QgbW9kdWxlID0gbW9kdWxlc0J5RmlsZW5hbWUuZ2V0KHNvdXJjZS5maWxlbmFtZSlcblxuICAgIGlmICghbW9kdWxlKSBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihkaWFnbm9zdGljTGFuZ3VhZ2UsXG4gICAgICBgQXBwbGljYXRpb24gc291cmNlICcke3NvdXJjZS5maWxlbmFtZX0nIGhhcyBubyBtYXRjaGluZyBzZW1hbnRpYyBtb2R1bGUgZm9yIGZhY2FkZSB2ZXJpZmljYXRpb24uYClcbiAgICByZXR1cm4ge1xuICAgICAgZmlsZW5hbWU6IHNvdXJjZS5maWxlbmFtZSxcbiAgICAgIGlkOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gKi8gKG1vZHVsZSkuaWQsXG4gICAgICBsYW5ndWFnZTogZmFjYWRlTGFuZ3VhZ2UsXG4gICAgICBzb3VyY2U6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoc291cmNlLmNvbnRlbnQpXG4gICAgfVxuICB9KVxuXG4gIGlmIChhcHBsaWNhdGlvblNvdXJjZXMubGVuZ3RoICE9IGFwcGxpY2F0aW9uTW9kdWxlcy5sZW5ndGgpIHtcbiAgICBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihkaWFnbm9zdGljTGFuZ3VhZ2UsIFwiRmFjYWRlIHZlcmlmaWNhdGlvbiByZXF1aXJlcyBvbmUgcmV0YWluZWQgYXBwbGljYXRpb24gc291cmNlIHBlciBzZW1hbnRpYyBtb2R1bGUuXCIpXG4gIH1cbiAgY29uc3QgcmVwYXJzZWQgPSBwYXJzZVByb2dyYW1Tb3VyY2Uoe2VudHJ5TW9kdWxlOiBwcm9ncmFtLmVudHJ5TW9kdWxlLCBzb3VyY2VzOiBhcHBsaWNhdGlvblNvdXJjZXN9KVxuICBjb25zdCBtb2R1bGVzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgcmVwYXJzZWQubW9kdWxlcykge1xuICAgIGlmICghbW9kdWxlLnN0ZGxpYkZhY2FkZSkgY29udGludWVcbiAgICBpZiAobW9kdWxlcy5oYXMobW9kdWxlLnN0ZGxpYkZhY2FkZS5pZGVudGl0eSkpIHtcbiAgICAgIGludmFsaWRGYWNhZGVEZXNjcmlwdG9yKGRpYWdub3N0aWNMYW5ndWFnZSwgYFJlZ2lzdGVyZWQgZmFjYWRlICcke21vZHVsZS5zdGRsaWJGYWNhZGUuaWRlbnRpdHl9JyByZXBhcnNlZCBtb3JlIHRoYW4gb25jZS5gKVxuICAgIH1cbiAgICBtb2R1bGVzLnNldChtb2R1bGUuc3RkbGliRmFjYWRlLmlkZW50aXR5LCBtb2R1bGUpXG4gIH1cbiAgcmV0dXJuIG1vZHVsZXNcbn1cblxuLyoqXG4gKiBDb21wYXJlcyBjbG9zZWQgcGxhaW4gSlNPTi1zaGFwZWQgZGF0YSB3aXRob3V0IGNvZXJjaW9uIG9yIGtleS1vcmRlciBhc3N1bXB0aW9ucy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gbGVmdCAtIENhbmRpZGF0ZSB2YWx1ZS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gcmlnaHQgLSBFeHBlY3RlZCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBFeGFjdCByZWN1cnNpdmUgZXF1aXZhbGVuY2UuXG4gKi9cbmZ1bmN0aW9uIGVxdWFsUGxhaW5EYXRhKGxlZnQsIHJpZ2h0KSB7XG4gIGlmIChsZWZ0ID09PSByaWdodCkgcmV0dXJuIHRydWVcbiAgaWYgKEFycmF5LmlzQXJyYXkobGVmdCkgfHwgQXJyYXkuaXNBcnJheShyaWdodCkpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShsZWZ0KSAmJiBBcnJheS5pc0FycmF5KHJpZ2h0KSAmJiBpc0RlbnNlQXJyYXkobGVmdCkgJiYgaXNEZW5zZUFycmF5KHJpZ2h0KSAmJlxuICAgICAgbGVmdC5sZW5ndGggPT0gcmlnaHQubGVuZ3RoICYmIGxlZnQuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gZXF1YWxQbGFpbkRhdGEodmFsdWUsIHJpZ2h0W2luZGV4XSkpXG4gIH1cbiAgaWYgKCFpc1BsYWluT2JqZWN0KGxlZnQpIHx8ICFpc1BsYWluT2JqZWN0KHJpZ2h0KSkgcmV0dXJuIGZhbHNlXG4gIGNvbnN0IGxlZnRLZXlzID0gT2JqZWN0LmtleXMobGVmdCkuc29ydCgpXG4gIGNvbnN0IHJpZ2h0S2V5cyA9IE9iamVjdC5rZXlzKHJpZ2h0KS5zb3J0KClcblxuICByZXR1cm4gbGVmdEtleXMubGVuZ3RoID09IHJpZ2h0S2V5cy5sZW5ndGggJiYgbGVmdEtleXMuZXZlcnkoKGtleSwgaW5kZXgpID0+XG4gICAga2V5ID09IHJpZ2h0S2V5c1tpbmRleF0gJiYgZXF1YWxQbGFpbkRhdGEobGVmdFtrZXldLCByaWdodFtrZXldKSlcbn1cblxuLyoqXG4gKiBUaHJvd3Mgb25lIHN0YWJsZSBmYWNhZGUgYXJ0aWZhY3QtYm91bmRhcnkgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIERpYWdub3N0aWMgZGV0YWlsLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBpbnZhbGlkRmFjYWRlRGVzY3JpcHRvcihsYW5ndWFnZSwgbWVzc2FnZSkge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlNURExJQl9GQUNBREVfREVTQ1JJUFRPUl9JTlZBTElEXCIsIGxhbmd1YWdlLCBtZXNzYWdlfSlcbn1cblxuLyoqXG4gKiBUaHJvd3Mgd2hlbiBhIGZhY2FkZSBzZW1hbnRpYyBib2R5IGV4Y2VlZHMgb3Igb21pdHMgaXRzIHJlZ2lzdHJ5LWRlY2xhcmVkIGF1dGhvcml0eS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIERpYWdub3N0aWMgZGV0YWlsLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBGYWNhZGUgc291cmNlIGxvY2F0aW9uLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBpbnZhbGlkRmFjYWRlQXV0aG9yaXR5KGxhbmd1YWdlLCBtZXNzYWdlLCBsb2NhdGlvbikge1xuICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlNURExJQl9GQUNBREVfQVVUSE9SSVRZX0ZPUkdFRFwiLCBsYW5ndWFnZSwgbG9jYXRpb24sIG1lc3NhZ2V9KVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgcHJvZ3JhbSBzdGRsaWIgbGluayBkZXNjcmlwdG9yIGFnYWluc3QgaXRzIGNhcGFiaWxpdHkgbW9kdWxlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtfSBwcm9ncmFtIC0gQ2FuZGlkYXRlIHByb2dyYW0uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGVbXX0gY2FwYWJpbGl0eU1vZHVsZXMgLSBNb2R1bGVzIGNhcnJ5aW5nIGNhcGFiaWxpdGllcy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVByb2dyYW1TdGRsaWJDb250cmFjdChwcm9ncmFtLCBsYW5ndWFnZSwgY2FwYWJpbGl0eU1vZHVsZXMpIHtcbiAgY29uc3QgY29udHJhY3QgPSBSZWZsZWN0LmdldChwcm9ncmFtLCBcInN0ZGxpYkNvbnRyYWN0XCIpXG4gIGNvbnN0IGNvbnRyYWN0cyA9IFJlZmxlY3QuZ2V0KHByb2dyYW0sIFwic3RkbGliQ29udHJhY3RzXCIpXG5cbiAgaWYgKGNhcGFiaWxpdHlNb2R1bGVzLmxlbmd0aCA9PSAwKSB7XG4gICAgaWYgKGNvbnRyYWN0ICE9PSB1bmRlZmluZWQgfHwgY29udHJhY3RzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICBjb2RlOiBcIlNURExJQl9MSU5LX0ZBSUxVUkVcIixcbiAgICAgICAgbGFuZ3VhZ2UsXG4gICAgICAgIG1lc3NhZ2U6IFwiQSBkZWNsYXJlZCBzdGFuZGFyZC1saWJyYXJ5IGNvbnRyYWN0IHJlcXVpcmVzIGNhcGFiaWxpdHkgbW9kdWxlcy5cIlxuICAgICAgfSlcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNvbnRyYWN0ICE9PSB1bmRlZmluZWQgJiYgY29udHJhY3RzICE9PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgIGNvZGU6IFwiU1RETElCX0xJTktfRkFJTFVSRVwiLFxuICAgICAgbGFuZ3VhZ2UsXG4gICAgICBtZXNzYWdlOiBcIkEgcHJvZ3JhbSBjYW5ub3QgZGVjbGFyZSBib3RoIHNpbmd1bGFyIGFuZCBwbHVyYWwgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdCBkZXNjcmlwdG9ycy5cIlxuICAgIH0pXG4gIH1cbiAgaWYgKGNvbnRyYWN0ID09PSB1bmRlZmluZWQgJiYgY29udHJhY3RzID09PSB1bmRlZmluZWQpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwicHJvZ3JhbSBtb2R1bGVzIHdpdGggY2FwYWJpbGl0aWVzIHJlcXVpcmUgYSBkZWNsYXJlZCBzdGFuZGFyZC1saWJyYXJ5IGNvbnRyYWN0XCIsXG4gICAgICBjYXBhYmlsaXR5TW9kdWxlc1swXS5sb2NhdGlvbilcbiAgfVxuICBjb25zdCBkZWNsYXJlZCA9IGNvbnRyYWN0cyA9PT0gdW5kZWZpbmVkID8gW2NvbnRyYWN0XSA6IGNvbnRyYWN0c1xuXG4gIGlmICghaXNEZW5zZUFycmF5KGRlY2xhcmVkKSB8fCBkZWNsYXJlZC5sZW5ndGggPT0gMCkge1xuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICBsYW5ndWFnZSxcbiAgICAgIG1lc3NhZ2U6IFwiVGhlIGRlY2xhcmVkIHN0YW5kYXJkLWxpYnJhcnkgY29udHJhY3QgZGVzY3JpcHRvciBsaXN0IGlzIG1hbGZvcm1lZCBvciBlbXB0eS5cIlxuICAgIH0pXG4gIH1cbiAgY29uc3QgaWRlbnRpdGllcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgZGVzY3JpcHRvciBvZiBkZWNsYXJlZCkge1xuICAgIGlmICghaXNQbGFpbk9iamVjdChkZXNjcmlwdG9yKSB8fCBPYmplY3Qua2V5cyhkZXNjcmlwdG9yKS5zb21lKChrZXkpID0+IGtleSAhPSBcImlkZW50aXR5XCIgJiYga2V5ICE9IFwiY29udHJhY3RWZXJzaW9uXCIpKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBcIlRoZSBkZWNsYXJlZCBzdGFuZGFyZC1saWJyYXJ5IGNvbnRyYWN0IGRlc2NyaXB0b3IgaXMgbWFsZm9ybWVkLlwiXG4gICAgICB9KVxuICAgIH1cbiAgICBjb25zdCBpZGVudGl0eSA9IGRlc2NyaXB0b3IuaWRlbnRpdHlcblxuICAgIGlmICh0eXBlb2YgaWRlbnRpdHkgIT0gXCJzdHJpbmdcIiB8fCBpZGVudGl0eS5sZW5ndGggPT0gMCB8fCBpZGVudGl0aWVzLmhhcyhpZGVudGl0eSkgfHxcbiAgICAgICFsaXN0U3RkbGliTW9kdWxlcygpLnNvbWUoKHtpZGVudGl0eTogcmVnaXN0ZXJlZH0pID0+IHJlZ2lzdGVyZWQgPT0gaWRlbnRpdHkpKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTElOS19GQUlMVVJFXCIsXG4gICAgICAgIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBgRGVjbGFyZWQgc3RhbmRhcmQtbGlicmFyeSBjb250cmFjdCAnJHtTdHJpbmcoaWRlbnRpdHkpfScgaXMgZHVwbGljYXRlIG9yIG5vdCBhIHJlZ2lzdGVyZWQgY2Fub25pY2FsIG1vZHVsZS5gXG4gICAgICB9KVxuICAgIH1cbiAgICBpZiAoZGVzY3JpcHRvci5jb250cmFjdFZlcnNpb24gIT09IHVuZGVmaW5lZCAmJiBwYXJzZVN0ZGxpYlZlcnNpb25SYW5nZShkZXNjcmlwdG9yLmNvbnRyYWN0VmVyc2lvbikgPT09IG51bGwpIHtcbiAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICBjb2RlOiBcIlNURExJQl9MSU5LX0ZBSUxVUkVcIixcbiAgICAgICAgbGFuZ3VhZ2UsXG4gICAgICAgIG1lc3NhZ2U6IGBEZWNsYXJlZCBzdGFuZGFyZC1saWJyYXJ5IGNvbnRyYWN0IHZlcnNpb24gJyR7U3RyaW5nKGRlc2NyaXB0b3IuY29udHJhY3RWZXJzaW9uKX0nIGlzIG5vdCBjYW5vbmljYWwuYFxuICAgICAgfSlcbiAgICB9XG4gICAgaWRlbnRpdGllcy5hZGQoaWRlbnRpdHkpXG4gIH1cbiAgZm9yIChjb25zdCBtb2R1bGUgb2YgY2FwYWJpbGl0eU1vZHVsZXMpIHtcbiAgICBmb3IgKGNvbnN0IGNhcGFiaWxpdHkgb2YgbW9kdWxlLmNhcGFiaWxpdGllcyA/PyBbXSkge1xuICAgICAgaWYgKCFpc1BsYWluT2JqZWN0KGNhcGFiaWxpdHkpIHx8IHR5cGVvZiBjYXBhYmlsaXR5LmF1dGhvcml0eUlkICE9IFwic3RyaW5nXCIgfHwgIWlkZW50aXRpZXMuaGFzKGNhcGFiaWxpdHkuYXV0aG9yaXR5SWQpKSB7XG4gICAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgICAgIGNvZGU6IFwiU1RETElCX0xJTktfRkFJTFVSRVwiLFxuICAgICAgICAgIGxhbmd1YWdlLFxuICAgICAgICAgIG1lc3NhZ2U6IGBDYXBhYmlsaXR5IGF1dGhvcml0eSAnJHtTdHJpbmcoUmVmbGVjdC5nZXQoY2FwYWJpbGl0eSwgXCJhdXRob3JpdHlJZFwiKSl9JyBkb2VzIG5vdCBtYXRjaCBhIGRlY2xhcmVkIHN0YW5kYXJkLWxpYnJhcnkgY29udHJhY3QuYFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIEZpbmRzIGEgcmVjb3JkIGNvbnN0cnVjdGlvbiB0aGF0IGNyb3NzZXMgYSB0eXBlLW9ubHkgaW1wb3J0IGVkZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gbW9kdWxlIC0gSW1wb3J0aW5nIHNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHR5cGVPbmx5RGVjbGFyYXRpb25JZHMgLSBJbXBvcnRlZCBpZGVudGl0aWVzIHVuYXZhaWxhYmxlIGluIHZhbHVlIHBvc2l0aW9ucy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmRDb25zdHJ1Y3Rpb24gfCB1bmRlZmluZWR9IEludmFsaWQgY29uc3RydWN0aW9uIHdoZW4gcHJlc2VudC5cbiAqL1xuZnVuY3Rpb24gZmluZFR5cGVPbmx5VmFsdWVDb25zdHJ1Y3Rpb24obW9kdWxlLCB0eXBlT25seURlY2xhcmF0aW9uSWRzKSB7XG4gIGlmICh0eXBlT25seURlY2xhcmF0aW9uSWRzLnNpemUgPT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKVxuXG4gIC8qKlxuICAgKiBWaXNpdHMgb25lIHNlbWFudGljIHZhbHVlLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHNlbWFudGljIHN1YnRyZWUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmRDb25zdHJ1Y3Rpb24gfCB1bmRlZmluZWR9IEludmFsaWQgY29uc3RydWN0aW9uIHdoZW4gcHJlc2VudC5cbiAgICovXG4gIGZ1bmN0aW9uIHZpc2l0KHZhbHVlKSB7XG4gICAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIHJldHVybiB1bmRlZmluZWRcbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBjb25zdCBvYmplY3QgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAodmFsdWUpXG5cbiAgICBpZiAob2JqZWN0LmtpbmQgPT0gXCJSZWNvcmRDb25zdHJ1Y3Rpb25cIiAmJiBpc1BsYWluT2JqZWN0KG9iamVjdC5yZWNvcmQpICYmXG4gICAgICB0eXBlb2Ygb2JqZWN0LnJlY29yZC5kZWNsYXJhdGlvbklkID09IFwic3RyaW5nXCIgJiYgdHlwZU9ubHlEZWNsYXJhdGlvbklkcy5oYXMob2JqZWN0LnJlY29yZC5kZWNsYXJhdGlvbklkKSkge1xuICAgICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkQ29uc3RydWN0aW9ufSAqLyAodmFsdWUpXG4gICAgfVxuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgT2JqZWN0LnZhbHVlcyhvYmplY3QpKSB7XG4gICAgICBjb25zdCBmb3VuZCA9IHZpc2l0KGNoaWxkKVxuXG4gICAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZFxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWRcbiAgfVxuXG4gIHJldHVybiB2aXNpdCh7ZW50cnlQb2ludDogbW9kdWxlLmVudHJ5UG9pbnQsIGZ1bmN0aW9uczogbW9kdWxlLmZ1bmN0aW9uc30pXG59XG5cbi8qKlxuICogUGxhbnMgYWxsIHBhdGhzIGJlZm9yZSBlbWlzc2lvbiBhbmQgcmVqZWN0cyBleGFjdC9jYXNlL2ZpbGUtZGlyZWN0b3J5IGNvbGxpc2lvbnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbX0gcHJvZ3JhbSAtIFZhbGlkYXRlZCBwcm9ncmFtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7U3RkbGliUHJvZ3JhbUxpbmtpbmcgfCBudWxsfSBbbGlua2luZ10gLSBQbGFubmVkIHN0ZGxpYiBwcm92aWRlciBsaW5rLlxuICogQHJldHVybnMge01hcDxzdHJpbmcsIHN0cmluZz59IFBhdGggYnkgbW9kdWxlIGlkZW50aXR5LlxuICovXG5mdW5jdGlvbiBwbGFuTW9kdWxlUGF0aHMocHJvZ3JhbSwgbGFuZ3VhZ2UsIGxpbmtpbmcgPSBudWxsKSB7XG4gIGNvbnN0IGV4dGVuc2lvbiA9IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiID8gXCIuanNcIiA6IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiID8gXCIudHNcIiA6IGxhbmd1YWdlID09IFwicnVieVwiID8gXCIucmJcIiA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IFwiLnBocFwiIDogXCIuamF2YVwiXG4gIGNvbnN0IHBhdGhzID0gbmV3IE1hcCgpXG4gIGNvbnN0IGZvbGRlZCA9IG5ldyBTZXQoKVxuICBjb25zdCB0YXJnZXRNb2R1bGVOYW1lcyA9IG5ldyBTZXQoKVxuICBjb25zdCBwcm92aWRlclBhdGhzID0gbGlua2luZyA/IGxpbmtpbmcubmVnb3RpYXRpb24ucHJvdmlkZXJzLm1hcCgoe21vZHVsZX0pID0+XG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zdGRsaWItcHJvdmlkZXJzLmpzXCIpLlN0ZGxpYlByb3ZpZGVyUmVjb3JkfSAqLyAobGlua2luZy5yZWNvcmRzLmdldChtb2R1bGUpKS5hcnRpZmFjdC5wYXRoKSA6IFtdXG4gIGNvbnN0IGZvbGRlZFByb3ZpZGVycyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgcHJvdmlkZXJQYXRoIG9mIHByb3ZpZGVyUGF0aHMpIHtcbiAgICBjb25zdCBrZXkgPSBwcm92aWRlclBhdGgudG9Mb2NhbGVMb3dlckNhc2UoXCJlbi1VU1wiKVxuXG4gICAgaWYgKCFpc1NhZmVBcnRpZmFjdFBhdGgocHJvdmlkZXJQYXRoKSB8fCBmb2xkZWQuaGFzKGtleSkpIHtcbiAgICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiU1RETElCX05BTUVfQ09MTElTSU9OXCIsIGxhbmd1YWdlLFxuICAgICAgICBtZXNzYWdlOiBgU3RkbGliIHByb3ZpZGVyIGFydGlmYWN0IHBhdGggJyR7cHJvdmlkZXJQYXRofScgaXMgdW5zYWZlIG9yIGNvbGxpZGluZy5gfSlcbiAgICB9XG4gICAgZm9sZGVkLmFkZChrZXkpXG4gICAgZm9sZGVkUHJvdmlkZXJzLnNldChwcm92aWRlclBhdGgudG9Mb2NhbGVMb3dlckNhc2UoXCJlbi1VU1wiKS5yZXBsYWNlQWxsKFwiLlwiLCBcIi9cIiksIHByb3ZpZGVyUGF0aClcbiAgfVxuXG4gIGZvciAoY29uc3QgbW9kdWxlIG9mIHByb2dyYW0ubW9kdWxlcykge1xuICAgIGxldCBwYXRoID0gYCR7bW9kdWxlLmlkLnJlcGxhY2VBbGwoXCIuXCIsIFwiL1wiKX0ke2V4dGVuc2lvbn1gXG4gICAgY29uc3QgcHJvdmlkZXJQYXRoID0gZm9sZGVkUHJvdmlkZXJzLmdldChwYXRoLnRvTG9jYWxlTG93ZXJDYXNlKFwiZW4tVVNcIikucmVwbGFjZUFsbChcIi5cIiwgXCIvXCIpKVxuXG4gICAgaWYgKHByb3ZpZGVyUGF0aCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtcbiAgICAgICAgY29kZTogXCJTVERMSUJfTkFNRV9DT0xMSVNJT05cIixcbiAgICAgICAgbGFuZ3VhZ2UsXG4gICAgICAgIG1lc3NhZ2U6IGBNb2R1bGUgcGF0aCAnJHtwYXRofScgY29sbGlkZXMgd2l0aCB0aGUgc3RkbGliIHByb3ZpZGVyIGFydGlmYWN0ICcke3Byb3ZpZGVyUGF0aH0nLmBcbiAgICAgIH0pXG4gICAgfVxuICAgIGNvbnN0IHRhcmdldE1vZHVsZU5hbWUgPSBtb2R1bGVDbGFzc05hbWUobW9kdWxlLmlkKVxuXG4gICAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIgfHwgbGFuZ3VhZ2UgPT0gXCJydWJ5XCIpIHtcbiAgICAgIGNvbnN0IGtleSA9IGxhbmd1YWdlID09IFwicGhwXCIgPyB0YXJnZXRNb2R1bGVOYW1lLnRvTG9jYWxlTG93ZXJDYXNlKFwiZW4tVVNcIikgOiB0YXJnZXRNb2R1bGVOYW1lXG5cbiAgICAgIGlmICh0YXJnZXRNb2R1bGVOYW1lcy5oYXMoa2V5KSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB0YXJnZXQgbW9kdWxlLW5hbWUgY29sbGlzaW9uICcke3RhcmdldE1vZHVsZU5hbWV9J2AsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIHRhcmdldE1vZHVsZU5hbWVzLmFkZChrZXkpXG4gICAgfVxuXG4gICAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIpIHtcbiAgICAgIHZhbGlkYXRlVGFyZ2V0SWRlbnRpZmllcihsYW5ndWFnZSwgdGFyZ2V0TW9kdWxlTmFtZSwgXCJtb2R1bGVcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgdmFsaWRhdGVUYXJnZXRUeXBlSWRlbnRpZmllcihsYW5ndWFnZSwgdGFyZ2V0TW9kdWxlTmFtZSwgbW9kdWxlLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJydWJ5XCIpIHZhbGlkYXRlVGFyZ2V0VHlwZUlkZW50aWZpZXIobGFuZ3VhZ2UsIHRhcmdldE1vZHVsZU5hbWUsIG1vZHVsZS5sb2NhdGlvbilcblxuICAgIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIikge1xuICAgICAgZm9yIChjb25zdCBzZWdtZW50IG9mIG1vZHVsZS5pZC5zcGxpdChcIi5cIikpIHZhbGlkYXRlVGFyZ2V0SWRlbnRpZmllcihsYW5ndWFnZSwgc2VnbWVudCwgXCJtb2R1bGVcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgY29uc3Qgbm9taW5hbENvdW50ID0gKG1vZHVsZS5yZWNvcmRzPy5sZW5ndGggPz8gMCkgKyAobW9kdWxlLmNsYXNzZXM/Lmxlbmd0aCA/PyAwKSArIChtb2R1bGUuZXJyb3JzPy5sZW5ndGggPz8gMClcblxuICAgICAgaWYgKG1vZHVsZS5pZC5pbmNsdWRlcyhcIi1cIikgfHwgbm9taW5hbENvdW50ID4gMSB8fFxuICAgICAgICBub21pbmFsQ291bnQgPiAwICYmIChtb2R1bGUuZnVuY3Rpb25zLmxlbmd0aCA+IDAgfHwgbW9kdWxlLmVudHJ5UG9pbnQpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJKYXZhIG1vZHVsZSBsYXlvdXQgcmVxdWlyaW5nIG11bHRpcGxlIHB1YmxpYyBkZWNsYXJhdGlvbnMgaW4gb25lIHNlbWFudGljIG1vZHVsZVwiLCBtb2R1bGUubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBjbGFzc05hbWUgPSBtb2R1bGUucmVjb3Jkcz8uWzBdPy5uYW1lID8/IG1vZHVsZS5jbGFzc2VzPy5bMF0/Lm5hbWUgPz8gbW9kdWxlLmVycm9ycz8uWzBdPy5uYW1lID8/XG4gICAgICAgIChtb2R1bGUuaWQgPT0gcHJvZ3JhbS5lbnRyeU1vZHVsZSA/IFwiTWFpblwiIDogdGFyZ2V0TW9kdWxlTmFtZSlcblxuICAgICAgaWYgKCEvXltBLVphLXpfJF1bQS1aYS16MC05XyRdKiQvdS50ZXN0KGNsYXNzTmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgaW52YWxpZCBKYXZhIHB1YmxpYyBjbGFzcyBuYW1lICcke2NsYXNzTmFtZX0nYCwgbW9kdWxlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKG1vZHVsZS5pZCAhPSBwcm9ncmFtLmVudHJ5TW9kdWxlKSB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyKGxhbmd1YWdlLCBjbGFzc05hbWUsIG1vZHVsZS5sb2NhdGlvbilcbiAgICAgIHBhdGggPSBgc2VtYW50aWZvbGQvZ2VuZXJhdGVkLyR7bW9kdWxlLmlkLnJlcGxhY2VBbGwoXCIuXCIsIFwiL1wiKX0vJHtjbGFzc05hbWV9LmphdmFgXG4gICAgfVxuICAgIGNvbnN0IGtleSA9IHBhdGgudG9Mb2NhbGVMb3dlckNhc2UoXCJlbi1VU1wiKVxuXG4gICAgaWYgKCFpc1NhZmVBcnRpZmFjdFBhdGgocGF0aCkgfHwgZm9sZGVkLmhhcyhrZXkpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB1bnNhZmUgb3IgY29sbGlkaW5nIHRhcmdldCBwYXRoICcke3BhdGh9J2AsIG1vZHVsZS5sb2NhdGlvbilcbiAgICBmb2xkZWQuYWRkKGtleSlcbiAgICBwYXRocy5zZXQobW9kdWxlLmlkLCBwYXRoKVxuICB9XG5cbiAgcmV0dXJuIHBhdGhzXG59XG5cbi8qKlxuICogQ29udmVydHMgYSBsb2dpY2FsIG1vZHVsZSBpZGVudGl0eSB0byBpdHMgY2Fub25pY2FsIHRhcmdldCB0eXBlIHNlZ21lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaWQgLSBMb2dpY2FsIG1vZHVsZSBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRhcmdldCBjbGFzcyBuYW1lLlxuICovXG5mdW5jdGlvbiBtb2R1bGVDbGFzc05hbWUoaWQpIHtcbiAgcmV0dXJuIGlkLnNwbGl0KC9bLl8tXSsvdSkubWFwKChwYXJ0KSA9PiBgJHtwYXJ0WzBdLnRvVXBwZXJDYXNlKCl9JHtwYXJ0LnNsaWNlKDEpfWApLmpvaW4oXCJcIilcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIGEgZGVjbGFyYXRpb24gb3IgYmluZGluZyBuYW1lIGZvciB0YXJnZXQgY29sbGlzaW9uIGNoZWNrcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIE5hbWUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBDb2xsaXNpb24ga2V5LlxuICovXG5mdW5jdGlvbiB0YXJnZXROYW1lKGxhbmd1YWdlLCBuYW1lKSB7XG4gIHJldHVybiBsYW5ndWFnZSA9PSBcInBocFwiID8gbmFtZS50b0xvY2FsZUxvd2VyQ2FzZShcImVuLVVTXCIpIDogbmFtZVxufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciBhIGNhbmRpZGF0ZSBpcyBhIGRpcmVjdCBwbGFpbiBvYmplY3QuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlLlxuICogQHJldHVybnMge3ZhbHVlIGlzIFJlY29yZDxzdHJpbmcsIHVua25vd24+fSBXaGV0aGVyIHRoZSB2YWx1ZSBpcyBhIHBsYWluIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gaXNQbGFpbk9iamVjdCh2YWx1ZSkge1xuICByZXR1cm4gQm9vbGVhbih2YWx1ZSkgJiYgdHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkodmFsdWUpICYmIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSkgPT0gT2JqZWN0LnByb3RvdHlwZVxufVxuXG4vKipcbiAqIFJhaXNlcyBhIHN0YWJsZSBtYWxmb3JtZWQgcHJvZ3JhbS1nZW5lcmF0aW9uIHJlcXVlc3QgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gU3RhYmxlIGZhaWx1cmUuXG4gKiBAcmV0dXJucyB7bmV2ZXJ9IEFsd2F5cyB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIGludmFsaWRQcm9ncmFtR2VuZXJhdGlvbihtZXNzYWdlKSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiSU5WQUxJRF9QUk9HUkFNXCIsIGxhbmd1YWdlOiBcInByb2dyYW1cIiwgbWVzc2FnZX0pXG59XG4iXX0=
|