semantifold 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -0,0 +1,989 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { isDenseArray } from "../array.js";
|
|
3
|
+
import { isSafeSourcePath } from "../artifact-path.js";
|
|
4
|
+
import { SemantifoldDiagnostic, semanticFailure, unsupportedCapability, unsupportedRole } from "../diagnostic.js";
|
|
5
|
+
import { languageRegistry } from "../language-registry.js";
|
|
6
|
+
import { normalizeCapabilityAuthority } from "../semantic/capabilities.js";
|
|
7
|
+
import { moduleLocation } from "../semantic/location.js";
|
|
8
|
+
import { annotateParsedModule } from "../semantic/provenance.js";
|
|
9
|
+
import { moduleUncheckedErrorEffects, validateParsedModule } from "../semantic/validate.js";
|
|
10
|
+
import { facadeCapabilityAuthority, resolveStdlibFacadeClosure, stdlibFacadeProgramDescriptor, stdlibFacadeRegistry } from "../stdlib-facades.js";
|
|
11
|
+
import { inspectJavaScriptTypeScriptModule } from "./javascript-typescript.js";
|
|
12
|
+
import { inspectJavaModule } from "./java.js";
|
|
13
|
+
import { inspectPhpModule } from "./php.js";
|
|
14
|
+
import { inspectRubyModule } from "./ruby.js";
|
|
15
|
+
const programLanguages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
16
|
+
const moduleIdPattern = /^[a-z][a-z0-9_]*(?:[.-][a-z][a-z0-9_]*)*$/u;
|
|
17
|
+
/** @typedef {{facade?: import("../stdlib-facades.js").StdlibFacadeRecord, filename: string, id: string, language: import("../semantic/types.js").SemanticLanguage, ownership: "application" | "facade", source: string}} ProgramSource */
|
|
18
|
+
/** @typedef {{declarationLocation?: import("../semantic/types.js").SourceLocation, facade?: import("../stdlib-facades.js").StdlibFacadeRecord, importedName: string, importedNameLocation?: import("../semantic/types.js").SourceLocation, localName: string, localNameLocation?: import("../semantic/types.js").SourceLocation, location: import("../semantic/types.js").SourceLocation, namespace?: boolean, pathLocation: import("../semantic/types.js").SourceLocation, specifier: string, stdlibCandidate?: true, typeOnly: boolean}} ProgramImportRequest */
|
|
19
|
+
/** @typedef {{importedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, nativeName: string, symbolKind: import("../semantic/types.js").SemanticDeclarationKind, typeOnly: boolean}} ProgramNativeBinding */
|
|
20
|
+
/** @typedef {{imports: ProgramImportRequest[], exports: {declarationLocation?: import("../semantic/types.js").SourceLocation, exportedName: string, exportedNameLocation?: import("../semantic/types.js").SourceLocation, localName: string, localNameLocation?: import("../semantic/types.js").SourceLocation, location: import("../semantic/types.js").SourceLocation, symbolKind?: import("../semantic/types.js").SemanticDeclarationKind, typeOnly: boolean}[], bindings?: ProgramNativeBinding[], nativeName?: string, nativeReferences?: {form: "constructor-call" | "receiver-call" | "unqualified-call", location: import("../semantic/types.js").SourceLocation, nativeModule: string, symbol: string}[]}} ProgramHeader */
|
|
21
|
+
/**
|
|
22
|
+
* Parses an explicit caller-supplied multi-source program without filesystem discovery.
|
|
23
|
+
* @param {object} input - Program parse request.
|
|
24
|
+
* @param {string} input.entryModule - Sole entry module identity.
|
|
25
|
+
* @param {{filename: string, id: string, language: import("../semantic/types.js").SemanticLanguage, source: string}[]} input.sources - Complete source set.
|
|
26
|
+
* @param {Readonly<import("../semantic/types.js").CapabilityAuthority> | import("../semantic/types.js").CapabilityAuthorityInput} [input.capabilityAuthority] - Explicit compiler authority.
|
|
27
|
+
* @returns {import("../semantic/types.js").SemanticProgram} Resolved semantic program.
|
|
28
|
+
*/
|
|
29
|
+
export function parseProgramSource(input) {
|
|
30
|
+
if (!isPlainObject(input) || !isDenseArray(input.sources) || input.sources.length == 0 ||
|
|
31
|
+
typeof input.entryModule != "string")
|
|
32
|
+
invalidProgram("Program parsing requires a non-empty ordered source set and entry module.");
|
|
33
|
+
const applicationSources = input.sources.map((source, index) => validateSource(source, index));
|
|
34
|
+
const requestedAuthority = normalizeCapabilityAuthority(input.capabilityAuthority);
|
|
35
|
+
const sourceLanguages = new Set(applicationSources.map(({ language }) => language));
|
|
36
|
+
if (sourceLanguages.size != 1) {
|
|
37
|
+
semanticFailure(applicationSources[0].language, "MIXED_SOURCE_LANGUAGES", "A semantic program must use one source-language compatibility profile.", undefined);
|
|
38
|
+
}
|
|
39
|
+
if (requestedAuthority && !languageRegistry.record(applicationSources[0].language).features.effectfulCapabilitiesAndResources) {
|
|
40
|
+
unsupportedCapability(applicationSources[0].language, "Task 034 effectful capabilities and owned resources", moduleLocation(applicationSources[0].filename, applicationSources[0].source));
|
|
41
|
+
}
|
|
42
|
+
const byId = new Map();
|
|
43
|
+
const byFilename = new Map();
|
|
44
|
+
for (const source of applicationSources) {
|
|
45
|
+
if (byId.has(source.id))
|
|
46
|
+
semanticFailure(source.language, "DUPLICATE_MODULE", `Duplicate module identity '${source.id}'.`, undefined);
|
|
47
|
+
if (byFilename.has(source.filename))
|
|
48
|
+
semanticFailure(source.language, "DUPLICATE_MODULE", `Duplicate module filename '${source.filename}'.`, undefined);
|
|
49
|
+
byId.set(source.id, source);
|
|
50
|
+
byFilename.set(source.filename, source);
|
|
51
|
+
}
|
|
52
|
+
if (!byId.has(input.entryModule)) {
|
|
53
|
+
semanticFailure(applicationSources[0].language, "INVALID_ENTRY_MODULE", `Unknown entry module '${input.entryModule}'.`, undefined);
|
|
54
|
+
}
|
|
55
|
+
const headers = new Map(applicationSources.map((source) => [source.id, inspectSource(source)]));
|
|
56
|
+
const facadeRoots = resolveFacadeImports(applicationSources, headers);
|
|
57
|
+
const facadeRecords = resolveStdlibFacadeClosure(facadeRoots);
|
|
58
|
+
if (facadeRecords.length > 0 && requestedAuthority) {
|
|
59
|
+
const located = applicationSources.flatMap((source) => requiredMapValue(headers, source.id).imports)
|
|
60
|
+
.find(({ facade }) => facade)?.location;
|
|
61
|
+
facadeFailure(applicationSources[0].language, "STDLIB_FACADE_AUTHORITY_FORGED", "Programs resolved through compiler-owned facades cannot supply their own canonical capability authority.", located);
|
|
62
|
+
}
|
|
63
|
+
const facadeAuthority = facadeCapabilityAuthority(facadeRecords);
|
|
64
|
+
const authority = requestedAuthority ?? (facadeAuthority ? normalizeCapabilityAuthority(facadeAuthority.input) : undefined);
|
|
65
|
+
const facadeSources = facadeRecords.map((facade) => /** @type {ProgramSource} */ ({
|
|
66
|
+
facade,
|
|
67
|
+
filename: facade.source.filename,
|
|
68
|
+
id: facade.source.id,
|
|
69
|
+
language: facade.language,
|
|
70
|
+
ownership: "facade",
|
|
71
|
+
source: facade.source.content
|
|
72
|
+
}));
|
|
73
|
+
validateFacadeCollisions(applicationSources, headers, facadeSources);
|
|
74
|
+
const sources = [...applicationSources, ...facadeSources];
|
|
75
|
+
for (const source of facadeSources) {
|
|
76
|
+
byId.set(source.id, source);
|
|
77
|
+
byFilename.set(source.filename, source);
|
|
78
|
+
headers.set(source.id, inspectSource(source));
|
|
79
|
+
}
|
|
80
|
+
const registeredSources = sources.map((source, index) => ({
|
|
81
|
+
content: source.source,
|
|
82
|
+
filename: source.filename,
|
|
83
|
+
id: `source:${index}`,
|
|
84
|
+
language: source.language,
|
|
85
|
+
ownership: source.ownership
|
|
86
|
+
}));
|
|
87
|
+
const sourceIds = new Map(sources.map((source, index) => [source.id, `source:${index}`]));
|
|
88
|
+
validateNativeModuleIdentities(sources, headers);
|
|
89
|
+
/** @type {Map<string, {source: typeof sources[number], requests: (ReturnType<typeof inspectSource>["imports"][number] & {moduleId: string})[]}>} */
|
|
90
|
+
const graph = new Map();
|
|
91
|
+
for (const source of sources) {
|
|
92
|
+
const requests = requiredMapValue(headers, source.id).imports.map((request) => ({
|
|
93
|
+
...request,
|
|
94
|
+
moduleId: request.facade?.source.id ?? resolveImportModule(source, request.specifier, request.pathLocation, byFilename, headers)
|
|
95
|
+
}));
|
|
96
|
+
graph.set(source.id, { requests, source });
|
|
97
|
+
}
|
|
98
|
+
const orderedIds = topologicalOrder(sources, graph);
|
|
99
|
+
/** @type {Map<string, import("../semantic/types.js").SemanticProgramModule>} */
|
|
100
|
+
const parsed = new Map();
|
|
101
|
+
/** @type {Map<string, Set<string>>} */
|
|
102
|
+
const callEffectsByDeclarationId = new Map();
|
|
103
|
+
for (const moduleId of orderedIds) {
|
|
104
|
+
const { requests, source } = requiredMapValue(graph, moduleId);
|
|
105
|
+
const sourceId = /** @type {string} */ (sourceIds.get(source.id));
|
|
106
|
+
const header = requiredMapValue(headers, moduleId);
|
|
107
|
+
const localNames = new Set();
|
|
108
|
+
const visibleFunctions = new Map();
|
|
109
|
+
const visibleCallEffects = new Map();
|
|
110
|
+
const visibleRecordsByName = new Map();
|
|
111
|
+
const visibleValueRecordsByName = new Map();
|
|
112
|
+
const visibleRecordsById = new Map();
|
|
113
|
+
const visibleClassesByName = new Map();
|
|
114
|
+
const visibleClassesById = new Map();
|
|
115
|
+
const visibleErrorsByName = new Map();
|
|
116
|
+
const visibleErrorsById = new Map();
|
|
117
|
+
const consumedBindings = new Set();
|
|
118
|
+
/** @type {import("../semantic/types.js").SemanticImport[]} */
|
|
119
|
+
const imports = [];
|
|
120
|
+
if (!source.facade && authority) {
|
|
121
|
+
const failureNames = new Set(header.imports.filter(({ facade }) => facade).flatMap(({ facade }) => facade?.publicDeclarations.flatMap((declaration) => declaration.kind == "function"
|
|
122
|
+
? declaration.failures
|
|
123
|
+
: [...declaration.constructor.failures, ...declaration.methods.flatMap(({ failures }) => failures)]) ?? []));
|
|
124
|
+
for (const failure of authority.capabilities.flatMap(({ failures }) => failures)) {
|
|
125
|
+
if (!failureNames.has(failure.name))
|
|
126
|
+
continue;
|
|
127
|
+
const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ ( /** @type {unknown} */(failure));
|
|
128
|
+
visibleErrorsByName.set(failure.name, declaration);
|
|
129
|
+
visibleErrorsById.set(failure.id, declaration);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
for (const request of requests) {
|
|
133
|
+
const dependency = parsed.get(request.moduleId);
|
|
134
|
+
if (!dependency) {
|
|
135
|
+
throw new Error(`Dependency '${request.moduleId}' was not parsed before '${source.id}'.`);
|
|
136
|
+
}
|
|
137
|
+
const dependencyHeader = requiredMapValue(headers, request.moduleId);
|
|
138
|
+
const nativeBindingPrefix = request.facade?.nativeModules.find(({ identity }) => identity == request.specifier)?.identity ??
|
|
139
|
+
dependencyHeader.nativeName;
|
|
140
|
+
const nativeBindings = source.language == "php" && request.namespace
|
|
141
|
+
? (header.bindings ?? []).filter(({ nativeName }) => nativeName.startsWith(`${nativeBindingPrefix}\\`))
|
|
142
|
+
: [];
|
|
143
|
+
const selectedExports = request.namespace && source.language == "php"
|
|
144
|
+
? dependency.exports.filter(({ exportedName }) => nativeBindings.some(({ importedName }) => importedName == exportedName))
|
|
145
|
+
: request.namespace
|
|
146
|
+
? dependency.exports
|
|
147
|
+
: dependency.exports.filter(({ exportedName }) => exportedName == request.importedName);
|
|
148
|
+
if (selectedExports.length == 0) {
|
|
149
|
+
semanticFailure(source.language, "UNRESOLVED_IMPORT", request.namespace
|
|
150
|
+
? `Imported module '${request.moduleId}' has no explicitly bound exports.`
|
|
151
|
+
: `Module '${request.moduleId}' does not export '${request.importedName}'.`, request.location);
|
|
152
|
+
}
|
|
153
|
+
for (const exported of selectedExports) {
|
|
154
|
+
const nativeBinding = nativeBindings.find(({ importedName }) => importedName == exported.exportedName);
|
|
155
|
+
const localName = nativeBinding?.localName ?? (request.namespace
|
|
156
|
+
? qualifiedImportName(source.language, dependencyHeader.nativeName, exported)
|
|
157
|
+
: request.localName);
|
|
158
|
+
const importLocation = nativeBinding?.location ?? request.location;
|
|
159
|
+
if (localNames.has(localName)) {
|
|
160
|
+
semanticFailure(source.language, "DUPLICATE_IMPORT_BINDING", `Duplicate import binding '${localName}'.`, importLocation);
|
|
161
|
+
}
|
|
162
|
+
localNames.add(localName);
|
|
163
|
+
if (nativeBinding && nativeBinding.symbolKind != exported.symbolKind &&
|
|
164
|
+
!(nativeBinding.symbolKind == "record" && exported.symbolKind == "error")) {
|
|
165
|
+
semanticFailure(source.language, "IMPORT_KIND_MISMATCH", `Import '${nativeBinding.importedName}' has the wrong declaration kind.`, importLocation);
|
|
166
|
+
}
|
|
167
|
+
if (request.typeOnly && exported.symbolKind != "record") {
|
|
168
|
+
semanticFailure(source.language, "IMPORT_KIND_MISMATCH", `Type import '${request.importedName}' does not name a record.`, importLocation);
|
|
169
|
+
}
|
|
170
|
+
if (nativeBinding)
|
|
171
|
+
consumedBindings.add(nativeBinding);
|
|
172
|
+
const declaration = declarationFor(dependency, exported);
|
|
173
|
+
const typeOnly = nativeBinding?.typeOnly ?? request.typeOnly;
|
|
174
|
+
if (exported.symbolKind == "function") {
|
|
175
|
+
visibleFunctions.set(localName, /** @type {import("../semantic/types.js").FunctionDeclaration} */ (declaration));
|
|
176
|
+
visibleCallEffects.set(localName, new Set(callEffectsByDeclarationId.get(exported.declarationId) ?? []));
|
|
177
|
+
}
|
|
178
|
+
else if (exported.symbolKind == "record") {
|
|
179
|
+
const record = /** @type {import("../semantic/types.js").RecordDeclaration} */ (declaration);
|
|
180
|
+
visibleRecordsByName.set(localName, record);
|
|
181
|
+
if (!typeOnly)
|
|
182
|
+
visibleValueRecordsByName.set(localName, record);
|
|
183
|
+
visibleRecordsById.set(/** @type {string} */ (record.id), record);
|
|
184
|
+
}
|
|
185
|
+
else if (exported.symbolKind == "class") {
|
|
186
|
+
const declaration = /** @type {import("../semantic/types.js").ClassDeclaration} */ (declarationFor(dependency, exported));
|
|
187
|
+
visibleClassesByName.set(localName, declaration);
|
|
188
|
+
visibleClassesById.set(/** @type {string} */ (declaration.id), declaration);
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
const error = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (declaration);
|
|
192
|
+
visibleErrorsByName.set(localName, error);
|
|
193
|
+
visibleErrorsById.set(/** @type {string} */ (error.id), error);
|
|
194
|
+
}
|
|
195
|
+
/** @type {Record<string, import("../semantic/types.js").SourceLocation>} */
|
|
196
|
+
const ranges = {
|
|
197
|
+
declaration: request.declarationLocation ?? request.location,
|
|
198
|
+
path: request.pathLocation
|
|
199
|
+
};
|
|
200
|
+
if (!request.namespace || nativeBinding || request.facade) {
|
|
201
|
+
ranges.importedName = nativeBinding?.location ?? request.importedNameLocation ?? importLocation;
|
|
202
|
+
ranges.localName = nativeBinding?.location ?? request.localNameLocation ?? importLocation;
|
|
203
|
+
}
|
|
204
|
+
imports.push({
|
|
205
|
+
declarationId: exported.declarationId,
|
|
206
|
+
importedName: exported.exportedName,
|
|
207
|
+
kind: "Import",
|
|
208
|
+
localName,
|
|
209
|
+
location: importLocation,
|
|
210
|
+
moduleId: request.moduleId,
|
|
211
|
+
...(request.facade ? { stdlibFacade: {
|
|
212
|
+
facadeIdentity: request.facade.identity,
|
|
213
|
+
facadeVersion: request.facade.version,
|
|
214
|
+
nativeModule: request.specifier,
|
|
215
|
+
nativeSymbol: exported.exportedName,
|
|
216
|
+
schema: /** @type {const} */ ("SemantifoldStdlibFacadeResolution"),
|
|
217
|
+
version: /** @type {const} */ (1)
|
|
218
|
+
} } : {}),
|
|
219
|
+
sourceProvenance: sourceAssociation(importLocation, ranges, sourceId),
|
|
220
|
+
symbolKind: exported.symbolKind,
|
|
221
|
+
typeOnly
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
const unconsumedBinding = (header.bindings ?? []).find((binding) => !consumedBindings.has(binding));
|
|
226
|
+
if (unconsumedBinding) {
|
|
227
|
+
semanticFailure(source.language, "UNRESOLVED_IMPORT", `Native import '${unconsumedBinding.nativeName}' has no matching required module.`, unconsumedBinding.location);
|
|
228
|
+
}
|
|
229
|
+
const frontend = /** @type {(input: object) => import("../semantic/types.js").SemanticModule} */ (languageRegistry.resolve(source.language, "frontend"));
|
|
230
|
+
const facadeModules = new Set(source.facade?.requirements.map(({ module }) => module) ?? []);
|
|
231
|
+
const moduleCapabilities = requestedAuthority?.capabilities ?? (source.facade?.requirements.length
|
|
232
|
+
? authority?.modules?.filter(({ identity }) => facadeModules.has(identity)).flatMap(({ capabilities }) => capabilities) ??
|
|
233
|
+
authority?.capabilities
|
|
234
|
+
: undefined);
|
|
235
|
+
const raw = frontend({
|
|
236
|
+
capabilities: moduleCapabilities,
|
|
237
|
+
filename: source.filename,
|
|
238
|
+
language: source.language,
|
|
239
|
+
program: {
|
|
240
|
+
classes: visibleClassesByName,
|
|
241
|
+
functions: visibleFunctions,
|
|
242
|
+
isEntry: source.id == input.entryModule,
|
|
243
|
+
errors: visibleErrorsByName,
|
|
244
|
+
records: visibleRecordsByName,
|
|
245
|
+
valueRecords: visibleValueRecordsByName
|
|
246
|
+
},
|
|
247
|
+
source: source.source
|
|
248
|
+
});
|
|
249
|
+
if (moduleCapabilities)
|
|
250
|
+
raw.capabilities = /** @type {import("../semantic/types.js").EffectCapabilityDeclaration[]} */ (moduleCapabilities);
|
|
251
|
+
if ((raw.classes?.length ?? 0) > 0 && !source.facade?.publicDeclarations.some(({ kind }) => kind == "class")) {
|
|
252
|
+
semanticFailure(source.language, "UNSUPPORTED_SYNTAX", "Task 033 reference classes are not supported by the Task 010 semantic program profile.", raw.classes?.[0]?.location ?? raw.location);
|
|
253
|
+
}
|
|
254
|
+
if (source.id == input.entryModule && raw.entryPoint.body.statements.length == 0) {
|
|
255
|
+
semanticFailure(source.language, "INVALID_ENTRY_MODULE", `Selected entry module '${source.id}' has no executable statements.`, raw.entryPoint.location);
|
|
256
|
+
}
|
|
257
|
+
try {
|
|
258
|
+
validateParsedModule(raw, source.language, {
|
|
259
|
+
callEffects: visibleCallEffects,
|
|
260
|
+
errors: visibleErrorsById,
|
|
261
|
+
functions: visibleFunctions,
|
|
262
|
+
records: visibleRecordsById,
|
|
263
|
+
classes: visibleClassesById
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
catch (error) {
|
|
267
|
+
const task037 = source.language == "ruby" && header.imports.some(({ facade }) => facade?.identity.startsWith("semantifold.task037."));
|
|
268
|
+
if (task037 && error instanceof SemantifoldDiagnostic && error.code == "UNKNOWN_METHOD" &&
|
|
269
|
+
error.detail.startsWith("Class 'TCPSocket'")) {
|
|
270
|
+
facadeFailure("ruby", "STDLIB_FACADE_MEMBER_UNSUPPORTED", error.detail, error.location);
|
|
271
|
+
}
|
|
272
|
+
throw error;
|
|
273
|
+
}
|
|
274
|
+
rekeyDeclarations(raw, source.id);
|
|
275
|
+
const localCallEffects = moduleUncheckedErrorEffects(raw, { callEffects: visibleCallEffects, functions: visibleFunctions });
|
|
276
|
+
for (const declaration of raw.functions) {
|
|
277
|
+
callEffectsByDeclarationId.set(/** @type {string} */ (declaration.id), new Set(localCallEffects.get(declaration.name) ?? []));
|
|
278
|
+
}
|
|
279
|
+
annotateParsedModule(raw, source);
|
|
280
|
+
rebaseParsedModuleProvenance(raw, registeredSources, sourceId);
|
|
281
|
+
/** @type {Map<string, {declaration: import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration, symbolKind: import("../semantic/types.js").SemanticDeclarationKind}>} */
|
|
282
|
+
const declarationsByName = new Map();
|
|
283
|
+
for (const declaration of raw.records ?? [])
|
|
284
|
+
declarationsByName.set(declaration.name, { declaration, symbolKind: "record" });
|
|
285
|
+
for (const declaration of raw.classes ?? [])
|
|
286
|
+
declarationsByName.set(declaration.name, { declaration, symbolKind: "class" });
|
|
287
|
+
for (const declaration of raw.errors ?? [])
|
|
288
|
+
declarationsByName.set(declaration.name, { declaration, symbolKind: "error" });
|
|
289
|
+
for (const declaration of raw.functions)
|
|
290
|
+
declarationsByName.set(declaration.name, { declaration, symbolKind: "function" });
|
|
291
|
+
/** @type {import("../semantic/types.js").SemanticExport[]} */
|
|
292
|
+
const exports = header.exports.map((request) => {
|
|
293
|
+
const resolved = declarationsByName.get(request.localName);
|
|
294
|
+
if (!resolved)
|
|
295
|
+
semanticFailure(source.language, "UNRESOLVED_EXPORT", `Unknown exported declaration '${request.localName}'.`, request.location);
|
|
296
|
+
if (request.typeOnly && resolved.symbolKind != "record") {
|
|
297
|
+
semanticFailure(source.language, "EXPORT_KIND_MISMATCH", `Type export '${request.exportedName}' does not name a record.`, request.location);
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
declarationId: /** @type {string} */ (resolved.declaration.id),
|
|
301
|
+
exportedName: request.exportedName,
|
|
302
|
+
kind: /** @type {const} */ ("Export"),
|
|
303
|
+
location: request.location,
|
|
304
|
+
sourceProvenance: sourceAssociation(request.location, {
|
|
305
|
+
declaration: request.declarationLocation ?? request.location,
|
|
306
|
+
exportedName: request.exportedNameLocation ?? request.location,
|
|
307
|
+
localName: request.localNameLocation ?? request.location
|
|
308
|
+
}, sourceId),
|
|
309
|
+
symbolKind: resolved.symbolKind
|
|
310
|
+
};
|
|
311
|
+
});
|
|
312
|
+
const exportedNames = new Set();
|
|
313
|
+
for (const exported of exports) {
|
|
314
|
+
if (exportedNames.has(exported.exportedName)) {
|
|
315
|
+
semanticFailure(source.language, "DUPLICATE_EXPORT", `Duplicate export '${exported.exportedName}'.`, exported.location);
|
|
316
|
+
}
|
|
317
|
+
exportedNames.add(exported.exportedName);
|
|
318
|
+
}
|
|
319
|
+
const { entryPoint, ...moduleWithoutEntry } = raw;
|
|
320
|
+
const module = /** @type {import("../semantic/types.js").SemanticProgramModule} */ ({
|
|
321
|
+
...moduleWithoutEntry,
|
|
322
|
+
...(source.id == input.entryModule ? { entryPoint } : {}),
|
|
323
|
+
exports,
|
|
324
|
+
id: source.id,
|
|
325
|
+
imports,
|
|
326
|
+
...(source.facade ? { stdlibFacade: { identity: source.facade.identity, version: source.facade.version } } : {}),
|
|
327
|
+
sourceFilename: source.filename
|
|
328
|
+
});
|
|
329
|
+
if (source.facade)
|
|
330
|
+
validateParsedFacade(source.facade, module);
|
|
331
|
+
parsed.set(source.id, module);
|
|
332
|
+
}
|
|
333
|
+
return {
|
|
334
|
+
entryModule: input.entryModule,
|
|
335
|
+
kind: "Program",
|
|
336
|
+
modules: orderedIds.map((id) => /** @type {import("../semantic/types.js").SemanticProgramModule} */ (parsed.get(id))),
|
|
337
|
+
...(requestedAuthority ? {
|
|
338
|
+
stdlibContract: {
|
|
339
|
+
identity: requestedAuthority.id,
|
|
340
|
+
...(requestedAuthority.contractVersion !== undefined ? { contractVersion: requestedAuthority.contractVersion } : {})
|
|
341
|
+
}
|
|
342
|
+
} : facadeAuthority && "contracts" in facadeAuthority ? { stdlibContracts: facadeAuthority.contracts }
|
|
343
|
+
: facadeAuthority ? { stdlibContract: facadeAuthority.contract } : {}),
|
|
344
|
+
...(facadeRecords.length > 0 ? { stdlibFacades: stdlibFacadeProgramDescriptor(applicationSources[0].language, facadeRecords) } : {}),
|
|
345
|
+
sources: registeredSources
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Resolves parser-owned native module and symbol evidence to facade roots.
|
|
350
|
+
* Mutating the private header requests keeps the proof attached to the exact import node.
|
|
351
|
+
* @param {ProgramSource[]} sources - Caller-owned sources.
|
|
352
|
+
* @param {Map<string, ProgramHeader>} headers - Parser-owned source headers.
|
|
353
|
+
* @returns {import("../stdlib-facades.js").StdlibFacadeRecord[]} Selected facade roots.
|
|
354
|
+
*/
|
|
355
|
+
function resolveFacadeImports(sources, headers) {
|
|
356
|
+
/** @type {import("../stdlib-facades.js").StdlibFacadeRecord[]} */
|
|
357
|
+
const roots = [];
|
|
358
|
+
for (const source of sources) {
|
|
359
|
+
const header = requiredMapValue(headers, source.id);
|
|
360
|
+
if (source.language == "ruby")
|
|
361
|
+
resolveRubyTask037Facades(source, header, roots);
|
|
362
|
+
if (source.language == "php") {
|
|
363
|
+
for (const binding of header.bindings ?? []) {
|
|
364
|
+
const parts = binding.nativeName.split("\\");
|
|
365
|
+
const symbol = /** @type {string} */ (parts.pop());
|
|
366
|
+
const nativeModule = parts.join("\\");
|
|
367
|
+
if (!nativeModule.startsWith("Semantifold\\Task036\\"))
|
|
368
|
+
continue;
|
|
369
|
+
const facade = resolveFacadeAt(source, nativeModule, symbol, binding.location);
|
|
370
|
+
header.imports.push({
|
|
371
|
+
declarationLocation: binding.location,
|
|
372
|
+
facade,
|
|
373
|
+
importedName: "*",
|
|
374
|
+
importedNameLocation: binding.location,
|
|
375
|
+
localName: "",
|
|
376
|
+
localNameLocation: binding.location,
|
|
377
|
+
location: binding.location,
|
|
378
|
+
namespace: true,
|
|
379
|
+
pathLocation: binding.location,
|
|
380
|
+
specifier: nativeModule,
|
|
381
|
+
stdlibCandidate: true,
|
|
382
|
+
typeOnly: false
|
|
383
|
+
});
|
|
384
|
+
roots.push(facade);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
for (const request of header.imports) {
|
|
388
|
+
const javaCandidate = source.language == "java" && request.specifier.startsWith("semantifold.task036.");
|
|
389
|
+
if (!request.stdlibCandidate && !javaCandidate)
|
|
390
|
+
continue;
|
|
391
|
+
if (request.facade)
|
|
392
|
+
continue;
|
|
393
|
+
if (/\.(?:bundle|dll|node|so)$/iu.test(request.specifier)) {
|
|
394
|
+
facadeFailure(source.language, "STDLIB_FACADE_NATIVE_EXTENSION_UNSUPPORTED", "Native-extension loading cannot participate in a portable stdlib facade.", request.pathLocation);
|
|
395
|
+
}
|
|
396
|
+
const supplied = [...headers.entries()].find(([, candidate]) => candidate.nativeName == request.specifier);
|
|
397
|
+
if (supplied) {
|
|
398
|
+
facadeFailure(source.language, "STDLIB_FACADE_SHADOWED", `Caller-supplied module '${supplied[0]}' replaces the catalogued native facade identity '${request.specifier}'.`, request.pathLocation);
|
|
399
|
+
}
|
|
400
|
+
const facade = request.namespace
|
|
401
|
+
? resolveFacadeModuleAt(source, request.specifier, request.pathLocation)
|
|
402
|
+
: resolveFacadeAt(source, request.specifier, request.importedName, request.importedNameLocation ?? request.location);
|
|
403
|
+
request.facade = facade;
|
|
404
|
+
roots.push(facade);
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
return roots;
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Resolves exact Task 037 Ruby references under a literal socket activation edge.
|
|
411
|
+
* @param {ProgramSource} source - Importing Ruby source.
|
|
412
|
+
* @param {ProgramHeader} header - Parser-owned Ruby header.
|
|
413
|
+
* @param {import("../stdlib-facades.js").StdlibFacadeRecord[]} roots - Selected facade roots.
|
|
414
|
+
* @returns {void}
|
|
415
|
+
*/
|
|
416
|
+
function resolveRubyTask037Facades(source, header, roots) {
|
|
417
|
+
const activationIndex = header.imports.findIndex(({ specifier, stdlibCandidate }) => stdlibCandidate && specifier == "socket");
|
|
418
|
+
if (activationIndex < 0)
|
|
419
|
+
return;
|
|
420
|
+
const activation = /** @type {ProgramImportRequest} */ (header.imports.splice(activationIndex, 1)[0]);
|
|
421
|
+
const bindings = new Set();
|
|
422
|
+
for (const reference of header.nativeReferences ?? []) {
|
|
423
|
+
if (reference.nativeModule != "socket" && reference.nativeModule != "ruby:Kernel")
|
|
424
|
+
continue;
|
|
425
|
+
const localName = reference.form == "receiver-call" ? "Kernel.puts" : reference.symbol;
|
|
426
|
+
if (bindings.has(localName))
|
|
427
|
+
continue;
|
|
428
|
+
bindings.add(localName);
|
|
429
|
+
const facade = resolveFacadeAt(source, reference.nativeModule, reference.symbol, reference.location);
|
|
430
|
+
header.imports.push({
|
|
431
|
+
declarationLocation: reference.location,
|
|
432
|
+
facade,
|
|
433
|
+
importedName: reference.symbol,
|
|
434
|
+
importedNameLocation: reference.location,
|
|
435
|
+
localName,
|
|
436
|
+
localNameLocation: reference.location,
|
|
437
|
+
location: reference.location,
|
|
438
|
+
pathLocation: activation.pathLocation,
|
|
439
|
+
specifier: reference.nativeModule,
|
|
440
|
+
stdlibCandidate: true,
|
|
441
|
+
typeOnly: false
|
|
442
|
+
});
|
|
443
|
+
roots.push(facade);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Resolves one exact native module and symbol while preserving parser location.
|
|
448
|
+
* @param {ProgramSource} source - Importing source.
|
|
449
|
+
* @param {string} nativeModule - Parser-proved native module identity.
|
|
450
|
+
* @param {string} symbol - Parser-proved native symbol.
|
|
451
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Identity evidence location.
|
|
452
|
+
* @returns {import("../stdlib-facades.js").StdlibFacadeRecord} Located exact native facade resolution.
|
|
453
|
+
*/
|
|
454
|
+
function resolveFacadeAt(source, nativeModule, symbol, location) {
|
|
455
|
+
try {
|
|
456
|
+
return stdlibFacadeRegistry.resolveFacade(source.language, nativeModule, symbol);
|
|
457
|
+
}
|
|
458
|
+
catch (error) {
|
|
459
|
+
if (error instanceof SemantifoldDiagnostic)
|
|
460
|
+
facadeFailure(source.language, error.code, error.detail, location);
|
|
461
|
+
throw error;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Resolves one exact namespace-style native module while preserving parser location.
|
|
466
|
+
* @param {ProgramSource} source - Importing source.
|
|
467
|
+
* @param {string} nativeModule - Parser-proved native module identity.
|
|
468
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Identity evidence location.
|
|
469
|
+
* @returns {import("../stdlib-facades.js").StdlibFacadeRecord} Located exact native facade-module resolution.
|
|
470
|
+
*/
|
|
471
|
+
function resolveFacadeModuleAt(source, nativeModule, location) {
|
|
472
|
+
try {
|
|
473
|
+
return stdlibFacadeRegistry.resolveModule(source.language, nativeModule);
|
|
474
|
+
}
|
|
475
|
+
catch (error) {
|
|
476
|
+
if (error instanceof SemantifoldDiagnostic)
|
|
477
|
+
facadeFailure(source.language, error.code, error.detail, location);
|
|
478
|
+
throw error;
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* Rejects caller capture of compiler-owned module/source/native names and imported bindings.
|
|
483
|
+
* @param {ProgramSource[]} applicationSources - Caller-owned sources.
|
|
484
|
+
* @param {Map<string, ProgramHeader>} headers - Caller parser headers.
|
|
485
|
+
* @param {ProgramSource[]} facadeSources - Selected compiler-owned facade sources.
|
|
486
|
+
* @returns {void}
|
|
487
|
+
*/
|
|
488
|
+
function validateFacadeCollisions(applicationSources, headers, facadeSources) {
|
|
489
|
+
const facadeIds = new Set(facadeSources.map(({ id }) => id));
|
|
490
|
+
const facadeFilenames = new Set(facadeSources.map(({ filename }) => filename));
|
|
491
|
+
const facadeNativeNames = new Set(facadeSources.map((source) => inspectSource(source).nativeName).filter(Boolean));
|
|
492
|
+
for (const source of applicationSources) {
|
|
493
|
+
const header = requiredMapValue(headers, source.id);
|
|
494
|
+
if (facadeIds.has(source.id) || facadeFilenames.has(source.filename)) {
|
|
495
|
+
facadeFailure(source.language, "STDLIB_FACADE_NAME_COLLISION", `Caller module '${source.id}' collides with a compiler-owned facade module or source path.`, moduleLocation(source.filename, source.source));
|
|
496
|
+
}
|
|
497
|
+
if (header.nativeName && facadeNativeNames.has(header.nativeName)) {
|
|
498
|
+
facadeFailure(source.language, "STDLIB_FACADE_REOPENED", `Caller source reopens the compiler-owned facade native identity '${header.nativeName}'.`, moduleLocation(source.filename, source.source));
|
|
499
|
+
}
|
|
500
|
+
const importedBindings = new Set(header.imports.filter(({ facade }) => facade && !facade.publicDeclarations.some(({ name }) => name == ""))
|
|
501
|
+
.flatMap((request) => request.namespace && source.language == "php"
|
|
502
|
+
? (header.bindings ?? []).filter(({ nativeName }) => nativeName.startsWith(`${request.specifier}\\`)).map(({ localName }) => localName)
|
|
503
|
+
: request.namespace ? [] : [request.localName]));
|
|
504
|
+
const shadowed = header.exports.find(({ localName }) => importedBindings.has(localName));
|
|
505
|
+
if (shadowed)
|
|
506
|
+
facadeFailure(source.language, "STDLIB_FACADE_SHADOWED", `Local declaration '${shadowed.localName}' shadows a parser-proved stdlib facade binding.`, shadowed.location);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* Validates a parsed compiler-owned facade against its registry declaration and canonical-only requirements.
|
|
511
|
+
* @param {import("../stdlib-facades.js").StdlibFacadeRecord} facade - Selected facade record.
|
|
512
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Parsed semantic module.
|
|
513
|
+
* @returns {void}
|
|
514
|
+
*/
|
|
515
|
+
function validateParsedFacade(facade, module) {
|
|
516
|
+
const exported = new Map(module.exports.map((item) => [item.exportedName, item]));
|
|
517
|
+
for (const declaration of facade.publicDeclarations) {
|
|
518
|
+
if (declaration.kind == "class") {
|
|
519
|
+
validateParsedFacadeClass(facade, module, declaration, exported.get(declaration.name));
|
|
520
|
+
continue;
|
|
521
|
+
}
|
|
522
|
+
const exportedDeclaration = exported.get(declaration.name);
|
|
523
|
+
const parsed = exportedDeclaration ? module.functions.find(({ id }) => id == exportedDeclaration.declarationId) : undefined;
|
|
524
|
+
const signatureMatches = parsed && parsed.parameters.length == declaration.parameters.length &&
|
|
525
|
+
parsed.parameters.every((parameter, index) => parameter.name == declaration.parameters[index].name &&
|
|
526
|
+
semanticTypeName(parameter.type) == declaration.parameters[index].type) &&
|
|
527
|
+
semanticTypeName(parsed.returnType) == declaration.returnType;
|
|
528
|
+
if (!signatureMatches)
|
|
529
|
+
facadeFailure(facade.language, "STDLIB_FACADE_DECLARATION_MISMATCH", `Facade '${facade.identity}' executable source does not match public declaration '${declaration.name}'.`, parsed?.location ?? module.location);
|
|
530
|
+
}
|
|
531
|
+
const dependencyIds = new Set(facade.dependencies.map((dependency) => stdlibFacadeRegistry.resolveIdentity(dependency.identity, facade.language, dependency.range).source.id));
|
|
532
|
+
if (module.imports.some(({ moduleId }) => !dependencyIds.has(moduleId)) ||
|
|
533
|
+
[...dependencyIds].some((moduleId) => !module.imports.some((imported) => imported.moduleId == moduleId))) {
|
|
534
|
+
facadeFailure(facade.language, "STDLIB_FACADE_DECLARATION_MISMATCH", `Facade '${facade.identity}' executable imports do not match its declared dependencies.`, module.location);
|
|
535
|
+
}
|
|
536
|
+
const allowedOperations = new Set(facade.requirements.flatMap(({ operations }) => operations));
|
|
537
|
+
const operationNames = new Map((module.capabilities ?? []).flatMap(({ operations }) => operations.map(({ id, name }) => [id, name])));
|
|
538
|
+
const usedOperations = collectEffectOperations(module, operationNames);
|
|
539
|
+
if ([...usedOperations].some((operation) => !allowedOperations.has(operation)) ||
|
|
540
|
+
[...allowedOperations].some((operation) => !usedOperations.has(operation))) {
|
|
541
|
+
facadeFailure(facade.language, "STDLIB_FACADE_AUTHORITY_FORGED", `Facade '${facade.identity}' canonical calls do not match its declared requirements.`, module.location);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
/**
|
|
545
|
+
* Verifies one executable compiler-owned facade class against its closed descriptor.
|
|
546
|
+
* @param {import("../stdlib-facades.js").StdlibFacadeRecord} facade - Owning facade.
|
|
547
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Parsed facade module.
|
|
548
|
+
* @param {import("../stdlib-facades.js").StdlibFacadeClassDeclaration} descriptor - Registry descriptor.
|
|
549
|
+
* @param {import("../semantic/types.js").SemanticExport | undefined} exported - Matching export evidence.
|
|
550
|
+
* @returns {void}
|
|
551
|
+
*/
|
|
552
|
+
function validateParsedFacadeClass(facade, module, descriptor, exported) {
|
|
553
|
+
const parsed = exported?.symbolKind == "class"
|
|
554
|
+
? module.classes?.find(({ id }) => id == exported.declarationId) : undefined;
|
|
555
|
+
const failureNames = new Map((module.capabilities ?? []).flatMap(({ failures }) => failures.map(({ id, name }) => [id, name])));
|
|
556
|
+
const constructorFailures = parsed?.constructor.failureIds?.map((id) => failureNames.get(id)) ?? [];
|
|
557
|
+
const constructorMatches = parsed?.name == descriptor.name && parsed.ownership?.kind == "ownedResource" &&
|
|
558
|
+
parsed.constructor.effects?.join(",") == descriptor.constructor.effects.join(",") &&
|
|
559
|
+
constructorFailures.join(",") == descriptor.constructor.failures.join(",") &&
|
|
560
|
+
parsed.constructor.parameters.length == descriptor.constructor.parameters.length &&
|
|
561
|
+
parsed.constructor.parameters.every((parameter, index) => parameter.name == descriptor.constructor.parameters[index].name &&
|
|
562
|
+
semanticTypeName(parameter.type) == descriptor.constructor.parameters[index].type);
|
|
563
|
+
const methodsMatch = parsed?.methods.length == descriptor.methods.length && descriptor.methods.every((expected, index) => {
|
|
564
|
+
const method = parsed?.methods[index];
|
|
565
|
+
const actualFailures = method?.failureIds?.map((id) => failureNames.get(id)) ?? [];
|
|
566
|
+
const operation = method?.body.statements.flatMap((statement) => {
|
|
567
|
+
const expression = statement.kind == "ExpressionStatement" || statement.kind == "ReturnStatement"
|
|
568
|
+
? statement.expression : statement.kind == "LocalDeclaration" ? statement.initializer : undefined;
|
|
569
|
+
return expression?.kind == "EffectCallExpression" ? [expression] : [];
|
|
570
|
+
})[0];
|
|
571
|
+
const flow = operation?.resolution.resourceFlow;
|
|
572
|
+
const terminalFailureId = flow?.kind == "borrow" || flow?.kind == "close" ? flow.terminalFailureId : undefined;
|
|
573
|
+
if (terminalFailureId)
|
|
574
|
+
actualFailures.push(failureNames.get(terminalFailureId));
|
|
575
|
+
return method?.name == expected.name && method.effects?.join(",") == expected.effects.join(",") &&
|
|
576
|
+
actualFailures.join(",") == expected.failures.join(",") && method.parameters.length == expected.parameters.length &&
|
|
577
|
+
method.parameters.every((parameter, parameterIndex) => parameter.name == expected.parameters[parameterIndex].name &&
|
|
578
|
+
semanticTypeName(parameter.type) == expected.parameters[parameterIndex].type) &&
|
|
579
|
+
semanticTypeName(method.returnType) == expected.returnType;
|
|
580
|
+
});
|
|
581
|
+
if (!constructorMatches || !methodsMatch) {
|
|
582
|
+
facadeFailure(facade.language, "STDLIB_FACADE_DECLARATION_MISMATCH", `Facade '${facade.identity}' executable source does not match public class '${descriptor.name}'.`, parsed?.location ?? module.location);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
/**
|
|
586
|
+
* Collects canonical operation names reached in one facade module.
|
|
587
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Parsed facade module.
|
|
588
|
+
* @param {Map<string, string>} operationNames - Canonical names by operation identity.
|
|
589
|
+
* @returns {Set<string>} Used operation names.
|
|
590
|
+
*/
|
|
591
|
+
function collectEffectOperations(module, operationNames) {
|
|
592
|
+
const used = new Set();
|
|
593
|
+
const seen = new WeakSet();
|
|
594
|
+
/**
|
|
595
|
+
* Visits one semantic subtree without following authority or provenance graphs.
|
|
596
|
+
* @param {unknown} value - Semantic subtree.
|
|
597
|
+
* @returns {void}
|
|
598
|
+
*/
|
|
599
|
+
function visit(value) {
|
|
600
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
601
|
+
return;
|
|
602
|
+
seen.add(value);
|
|
603
|
+
if (!Array.isArray(value) && Reflect.get(value, "kind") == "EffectCallExpression") {
|
|
604
|
+
const name = operationNames.get(Reflect.get(value, "operation"));
|
|
605
|
+
if (name)
|
|
606
|
+
used.add(name);
|
|
607
|
+
}
|
|
608
|
+
for (const [key, child] of Object.entries(value)) {
|
|
609
|
+
if (key != "capabilities" && key != "location" && key != "provenance" && key != "sourceProvenance")
|
|
610
|
+
visit(child);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
visit(module);
|
|
614
|
+
return used;
|
|
615
|
+
}
|
|
616
|
+
/**
|
|
617
|
+
* Converts one parsed semantic type to the facade declaration vocabulary.
|
|
618
|
+
* @param {import("../semantic/types.js").SemanticFunctionReturnType} type - Parsed type.
|
|
619
|
+
* @returns {string} Closed canonical public type name.
|
|
620
|
+
*/
|
|
621
|
+
function semanticTypeName(type) {
|
|
622
|
+
if (type.kind == "TypeReference")
|
|
623
|
+
return type.name;
|
|
624
|
+
return type.kind == "OptionalType" && type.valueType.kind == "TypeReference"
|
|
625
|
+
? `optional:${type.valueType.name}` : "unsupported";
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Throws one stable located facade diagnostic.
|
|
629
|
+
* @param {string} language - Source language.
|
|
630
|
+
* @param {string} code - Stable diagnostic code.
|
|
631
|
+
* @param {string} message - Diagnostic detail.
|
|
632
|
+
* @param {import("../semantic/types.js").SourceLocation | undefined} location - Parser-owned location.
|
|
633
|
+
* @returns {never} Always throws.
|
|
634
|
+
*/
|
|
635
|
+
function facadeFailure(language, code, message, location) {
|
|
636
|
+
throw new SemantifoldDiagnostic({ code, language, location, message });
|
|
637
|
+
}
|
|
638
|
+
/**
|
|
639
|
+
* Rejects source-profile identities whose lookup or reopening would depend on caller order.
|
|
640
|
+
* @param {ProgramSource[]} sources - Complete validated source set.
|
|
641
|
+
* @param {Map<string, ProgramHeader>} headers - Parser-owned module headers.
|
|
642
|
+
* @returns {void}
|
|
643
|
+
*/
|
|
644
|
+
function validateNativeModuleIdentities(sources, headers) {
|
|
645
|
+
if (!sources.every(({ language }) => language == "java") && !sources.every(({ language }) => language == "ruby"))
|
|
646
|
+
return;
|
|
647
|
+
const ordered = [...sources].sort((left, right) => left.filename.localeCompare(right.filename, "en-US") ||
|
|
648
|
+
left.id.localeCompare(right.id, "en-US"));
|
|
649
|
+
const owners = new Map();
|
|
650
|
+
for (const source of ordered) {
|
|
651
|
+
const nativeName = requiredMapValue(headers, source.id).nativeName;
|
|
652
|
+
if (!nativeName)
|
|
653
|
+
continue;
|
|
654
|
+
const earlier = owners.get(nativeName);
|
|
655
|
+
if (earlier) {
|
|
656
|
+
const label = source.language == "java" ? "Java" : "Ruby";
|
|
657
|
+
semanticFailure(source.language, "DUPLICATE_MODULE", `Duplicate ${label} native module identity '${nativeName}' in '${earlier.filename}' and '${source.filename}'.`, moduleLocation(source.filename, source.source));
|
|
658
|
+
}
|
|
659
|
+
owners.set(nativeName, source);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Validates and snapshots one caller-supplied program source descriptor.
|
|
664
|
+
* @param {unknown} candidate - Candidate source descriptor.
|
|
665
|
+
* @param {number} index - Source index.
|
|
666
|
+
* @returns {ProgramSource} Validated source descriptor.
|
|
667
|
+
*/
|
|
668
|
+
function validateSource(candidate, index) {
|
|
669
|
+
if (!isPlainObject(candidate)) {
|
|
670
|
+
return invalidProgram(`Program source ${index} requires a stable module ID, safe filename, language, and source text.`);
|
|
671
|
+
}
|
|
672
|
+
if (!isPlainObject(candidate) || typeof candidate.id != "string" || !moduleIdPattern.test(candidate.id) ||
|
|
673
|
+
typeof candidate.filename != "string" || !isSafeSourcePath(candidate.filename) ||
|
|
674
|
+
typeof candidate.source != "string" || typeof candidate.language != "string") {
|
|
675
|
+
invalidProgram(`Program source ${index} requires a stable module ID, safe filename, language, and source text.`);
|
|
676
|
+
}
|
|
677
|
+
languageRegistry.record(candidate.language);
|
|
678
|
+
if (!programLanguages.has(candidate.language))
|
|
679
|
+
unsupportedRole(candidate.language, "multi-file frontend");
|
|
680
|
+
return /** @type {ProgramSource} */ ({
|
|
681
|
+
filename: candidate.filename,
|
|
682
|
+
id: candidate.id,
|
|
683
|
+
language: candidate.language,
|
|
684
|
+
ownership: "application",
|
|
685
|
+
source: candidate.source
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
/**
|
|
689
|
+
* Dispatches parser-owned module header inspection for one cohort source.
|
|
690
|
+
* @param {{filename: string, language: import("../semantic/types.js").SemanticLanguage, source: string}} source - Validated source.
|
|
691
|
+
* @returns {ProgramHeader} Parser-owned import/export header.
|
|
692
|
+
*/
|
|
693
|
+
function inspectSource(source) {
|
|
694
|
+
if (source.language == "javascript" || source.language == "typescript") {
|
|
695
|
+
return inspectJavaScriptTypeScriptModule(/** @type {{filename: string, language: "javascript" | "typescript", source: string}} */ (source));
|
|
696
|
+
}
|
|
697
|
+
if (source.language == "ruby") {
|
|
698
|
+
return inspectRubyModule(/** @type {{filename: string, language: "ruby", source: string}} */ (source));
|
|
699
|
+
}
|
|
700
|
+
if (source.language == "php") {
|
|
701
|
+
return inspectPhpModule(/** @type {{filename: string, language: "php", source: string}} */ (source));
|
|
702
|
+
}
|
|
703
|
+
if (source.language == "java") {
|
|
704
|
+
return inspectJavaModule(/** @type {{filename: string, language: "java", source: string}} */ (source));
|
|
705
|
+
}
|
|
706
|
+
return unsupportedRole(source.language, "multi-file frontend");
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* Resolves only an explicit relative ESM specifier against caller-supplied filenames.
|
|
710
|
+
* @param {{filename: string, language: import("../semantic/types.js").SemanticLanguage}} source - Importing source.
|
|
711
|
+
* @param {string} specifier - Parser-owned relative specifier.
|
|
712
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Specifier location.
|
|
713
|
+
* @param {Map<string, ProgramSource>} sources - Sources by exact filename.
|
|
714
|
+
* @param {Map<string, ProgramHeader>} headers - Parser-owned module headers.
|
|
715
|
+
* @returns {string} Resolved module identity.
|
|
716
|
+
*/
|
|
717
|
+
function resolveImportModule(source, specifier, location, sources, headers) {
|
|
718
|
+
if (source.language == "java") {
|
|
719
|
+
const matched = [...headers.entries()].find(([, header]) => header.nativeName == specifier);
|
|
720
|
+
if (!matched)
|
|
721
|
+
semanticFailure(source.language, "UNRESOLVED_MODULE", `Import '${specifier}' does not identify a supplied source.`, location);
|
|
722
|
+
return matched[0];
|
|
723
|
+
}
|
|
724
|
+
const directory = source.filename.split("/").slice(0, -1);
|
|
725
|
+
const parts = [...directory];
|
|
726
|
+
for (const part of specifier.split("/")) {
|
|
727
|
+
if (part == "" || part == ".")
|
|
728
|
+
continue;
|
|
729
|
+
if (part == "..") {
|
|
730
|
+
if (parts.length == 0)
|
|
731
|
+
semanticFailure(source.language, "UNSAFE_MODULE_PATH", `Import '${specifier}' escapes the supplied source root.`, location);
|
|
732
|
+
parts.pop();
|
|
733
|
+
}
|
|
734
|
+
else
|
|
735
|
+
parts.push(part);
|
|
736
|
+
}
|
|
737
|
+
let exact = parts.join("/");
|
|
738
|
+
if (source.language == "ruby" && !exact.endsWith(".rb"))
|
|
739
|
+
exact += ".rb";
|
|
740
|
+
const candidates = [exact];
|
|
741
|
+
if (source.language == "typescript" && exact.endsWith(".js"))
|
|
742
|
+
candidates.push(`${exact.slice(0, -3)}.ts`);
|
|
743
|
+
const matched = candidates.flatMap((filename) => sources.has(filename) ? [sources.get(filename)] : [])[0];
|
|
744
|
+
if (!matched)
|
|
745
|
+
semanticFailure(source.language, "UNRESOLVED_MODULE", `Import '${specifier}' does not identify a supplied source.`, location);
|
|
746
|
+
return matched.id;
|
|
747
|
+
}
|
|
748
|
+
/**
|
|
749
|
+
* Builds the source-profile spelling used to resolve one namespace-qualified import.
|
|
750
|
+
* @param {import("../semantic/types.js").SemanticLanguage} language - Importing source language.
|
|
751
|
+
* @param {string | undefined} nativeName - Dependency namespace/module name.
|
|
752
|
+
* @param {import("../semantic/types.js").SemanticExport} exported - Imported export.
|
|
753
|
+
* @returns {string} Source-profile binding spelling.
|
|
754
|
+
*/
|
|
755
|
+
function qualifiedImportName(language, nativeName, exported) {
|
|
756
|
+
if (!nativeName)
|
|
757
|
+
throw new Error("Namespace import dependency has no parser-owned native name.");
|
|
758
|
+
if (language == "ruby")
|
|
759
|
+
return `${nativeName}${exported.symbolKind == "function" ? "." : "::"}${exported.exportedName}`;
|
|
760
|
+
if (language == "java") {
|
|
761
|
+
const className = nativeName.split(".").at(-1);
|
|
762
|
+
if (!className)
|
|
763
|
+
throw new Error("Java import dependency has no class name.");
|
|
764
|
+
return exported.symbolKind == "function" ? `${className}.${exported.exportedName}` : className;
|
|
765
|
+
}
|
|
766
|
+
throw new Error(`Unsupported namespace import profile '${language}'.`);
|
|
767
|
+
}
|
|
768
|
+
/**
|
|
769
|
+
* Sorts the explicit module graph in stable dependency-first order.
|
|
770
|
+
* @param {ProgramSource[]} sources - Validated sources.
|
|
771
|
+
* @param {Map<string, {source: ProgramSource, requests: {moduleId: string, location: import("../semantic/types.js").SourceLocation}[]}>} graph - Resolved graph.
|
|
772
|
+
* @returns {string[]} Dependency-first module identities.
|
|
773
|
+
*/
|
|
774
|
+
function topologicalOrder(sources, graph) {
|
|
775
|
+
const complete = new Set();
|
|
776
|
+
const active = new Set();
|
|
777
|
+
/** @type {string[]} */
|
|
778
|
+
const result = [];
|
|
779
|
+
/**
|
|
780
|
+
* Visits one module and its dependencies.
|
|
781
|
+
* @param {string} id - Module identity.
|
|
782
|
+
*/
|
|
783
|
+
function visit(id) {
|
|
784
|
+
if (complete.has(id))
|
|
785
|
+
return;
|
|
786
|
+
if (active.has(id)) {
|
|
787
|
+
const edge = requiredMapValue(graph, id).requests[0];
|
|
788
|
+
semanticFailure(requiredMapValue(graph, id).source.language, "IMPORT_CYCLE", `Import cycle includes module '${id}'.`, edge?.location);
|
|
789
|
+
}
|
|
790
|
+
active.add(id);
|
|
791
|
+
for (const request of requiredMapValue(graph, id).requests)
|
|
792
|
+
visit(request.moduleId);
|
|
793
|
+
active.delete(id);
|
|
794
|
+
complete.add(id);
|
|
795
|
+
result.push(id);
|
|
796
|
+
}
|
|
797
|
+
for (const source of sources)
|
|
798
|
+
visit(source.id);
|
|
799
|
+
return result;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Looks up one already-resolved exported declaration.
|
|
803
|
+
* @param {import("../semantic/types.js").SemanticProgramModule} module - Exporting module.
|
|
804
|
+
* @param {import("../semantic/types.js").SemanticExport} exported - Resolved export.
|
|
805
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").ErrorDeclaration} Declaration.
|
|
806
|
+
*/
|
|
807
|
+
function declarationFor(module, exported) {
|
|
808
|
+
const declarations = exported.symbolKind == "function" ? module.functions :
|
|
809
|
+
exported.symbolKind == "record" ? module.records ?? [] : exported.symbolKind == "class" ? module.classes ?? [] : module.errors ?? [];
|
|
810
|
+
const declaration = declarations.find(({ id }) => id == exported.declarationId);
|
|
811
|
+
if (!declaration)
|
|
812
|
+
throw new Error(`Resolved export '${exported.declarationId}' has no declaration.`);
|
|
813
|
+
return declaration;
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Prefixes module-owned declaration identities and explicit resolved references to them.
|
|
817
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Validated module.
|
|
818
|
+
* @param {string} moduleId - Stable module identity.
|
|
819
|
+
* @returns {void}
|
|
820
|
+
*/
|
|
821
|
+
function rekeyDeclarations(module, moduleId) {
|
|
822
|
+
const replacements = new Map();
|
|
823
|
+
for (const declaration of module.classes ?? []) {
|
|
824
|
+
replacements.set(declaration.id, `${moduleId}#${declaration.id}`);
|
|
825
|
+
replacements.set(declaration.constructor.id, `${moduleId}#${declaration.constructor.id}`);
|
|
826
|
+
for (const field of declaration.fields)
|
|
827
|
+
replacements.set(field.id, `${moduleId}#${field.id}`);
|
|
828
|
+
for (const method of declaration.methods)
|
|
829
|
+
replacements.set(method.id, `${moduleId}#${method.id}`);
|
|
830
|
+
}
|
|
831
|
+
for (const declaration of module.records ?? []) {
|
|
832
|
+
replacements.set(declaration.id, `${moduleId}#${declaration.id}`);
|
|
833
|
+
for (const parameter of declaration.typeParameters ?? []) {
|
|
834
|
+
if (parameter.id)
|
|
835
|
+
replacements.set(parameter.id, `${moduleId}#${parameter.id}`);
|
|
836
|
+
}
|
|
837
|
+
for (const field of declaration.fields)
|
|
838
|
+
replacements.set(field.id, `${moduleId}#${field.id}`);
|
|
839
|
+
}
|
|
840
|
+
for (const declaration of module.errors ?? [])
|
|
841
|
+
replacements.set(declaration.id, `${moduleId}#${declaration.id}`);
|
|
842
|
+
for (const declaration of module.functions) {
|
|
843
|
+
replacements.set(declaration.id, `${moduleId}#${declaration.id}`);
|
|
844
|
+
for (const parameter of declaration.typeParameters ?? []) {
|
|
845
|
+
if (parameter.id)
|
|
846
|
+
replacements.set(parameter.id, `${moduleId}#${parameter.id}`);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
for (const declaration of module.records ?? []) {
|
|
850
|
+
declaration.id = replacements.get(declaration.id);
|
|
851
|
+
for (const parameter of declaration.typeParameters ?? []) {
|
|
852
|
+
parameter.id = /** @type {string} */ (replacements.get(/** @type {string} */ (parameter.id)));
|
|
853
|
+
}
|
|
854
|
+
for (const field of declaration.fields)
|
|
855
|
+
field.id = /** @type {string} */ (replacements.get(field.id));
|
|
856
|
+
}
|
|
857
|
+
for (const declaration of module.errors ?? [])
|
|
858
|
+
declaration.id = replacements.get(declaration.id);
|
|
859
|
+
for (const declaration of module.classes ?? []) {
|
|
860
|
+
declaration.id = replacements.get(declaration.id);
|
|
861
|
+
declaration.constructor.id = replacements.get(declaration.constructor.id);
|
|
862
|
+
for (const field of declaration.fields)
|
|
863
|
+
field.id = replacements.get(field.id);
|
|
864
|
+
for (const method of declaration.methods)
|
|
865
|
+
method.id = replacements.get(method.id);
|
|
866
|
+
if (declaration.ownership?.kind == "ownedResource") {
|
|
867
|
+
declaration.ownership.fieldId = /** @type {string} */ (replacements.get(declaration.ownership.fieldId));
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
for (const declaration of module.functions) {
|
|
871
|
+
declaration.id = replacements.get(declaration.id);
|
|
872
|
+
for (const parameter of declaration.typeParameters ?? []) {
|
|
873
|
+
parameter.id = /** @type {string} */ (replacements.get(/** @type {string} */ (parameter.id)));
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
const seen = new WeakSet();
|
|
877
|
+
/**
|
|
878
|
+
* Rewrites only typed identity-bearing fields throughout one semantic subtree.
|
|
879
|
+
* @param {unknown} value - Semantic subtree.
|
|
880
|
+
*/
|
|
881
|
+
function visit(value) {
|
|
882
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
883
|
+
return;
|
|
884
|
+
seen.add(value);
|
|
885
|
+
const object = /** @type {Record<string, unknown>} */ (value);
|
|
886
|
+
if ((object.kind == "RecordType" || object.kind == "ReferenceType" || object.kind == "OwnedReferenceType" ||
|
|
887
|
+
object.kind == "ErrorType" || object.kind == "ResolvedFunctionSignature" ||
|
|
888
|
+
object.kind == "ResolvedConstructorSignature" || object.kind == "ResolvedMethodSignature") &&
|
|
889
|
+
typeof object.declarationId == "string" && replacements.has(object.declarationId)) {
|
|
890
|
+
object.declarationId = replacements.get(object.declarationId);
|
|
891
|
+
}
|
|
892
|
+
if ((object.kind == "MemberRead" || object.kind == "PrivateFieldRead" || object.kind == "PrivateFieldWriteStatement") &&
|
|
893
|
+
typeof object.field == "string" && replacements.has(object.field)) {
|
|
894
|
+
object.field = replacements.get(object.field);
|
|
895
|
+
}
|
|
896
|
+
if (object.kind == "MethodCallExpression" && typeof object.method == "string" && replacements.has(object.method)) {
|
|
897
|
+
object.method = replacements.get(object.method);
|
|
898
|
+
}
|
|
899
|
+
if (object.kind == "ReceiverExpression" && typeof object.classId == "string" && replacements.has(object.classId)) {
|
|
900
|
+
object.classId = replacements.get(object.classId);
|
|
901
|
+
}
|
|
902
|
+
if (object.kind == "TypeVariableReference" && typeof object.parameterId == "string" && replacements.has(object.parameterId)) {
|
|
903
|
+
object.parameterId = replacements.get(object.parameterId);
|
|
904
|
+
}
|
|
905
|
+
for (const child of Object.values(object))
|
|
906
|
+
if (typeof child == "object")
|
|
907
|
+
visit(child);
|
|
908
|
+
}
|
|
909
|
+
visit(module);
|
|
910
|
+
}
|
|
911
|
+
/**
|
|
912
|
+
* Creates a source association for a parser-owned module header node.
|
|
913
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Node origin.
|
|
914
|
+
* @param {Readonly<Record<string, import("../semantic/types.js").SourceLocation>>} ranges - Exact available header roles.
|
|
915
|
+
* @param {string} sourceId - Program-wide source identity.
|
|
916
|
+
* @returns {import("../semantic/types.js").SemanticNodeSourceProvenance} Source association.
|
|
917
|
+
*/
|
|
918
|
+
function sourceAssociation(location, ranges, sourceId) {
|
|
919
|
+
return {
|
|
920
|
+
origin: { kind: "source", location, sourceId },
|
|
921
|
+
ranges,
|
|
922
|
+
schema: "SemantifoldNodeProvenance",
|
|
923
|
+
version: 1
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Rebinds one parser-local provenance registry to the complete program source registry.
|
|
928
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Newly parsed module.
|
|
929
|
+
* @param {import("../semantic/types.js").RegisteredSource[]} sources - Program-wide registry.
|
|
930
|
+
* @param {string} sourceId - Owning source identity.
|
|
931
|
+
* @returns {void}
|
|
932
|
+
*/
|
|
933
|
+
function rebaseParsedModuleProvenance(module, sources, sourceId) {
|
|
934
|
+
if (!module.provenance)
|
|
935
|
+
throw new Error("Parsed program module has no source provenance.");
|
|
936
|
+
const seen = new WeakSet();
|
|
937
|
+
/**
|
|
938
|
+
* Rebinds source-origin identities throughout one semantic subtree.
|
|
939
|
+
* @param {unknown} value - Semantic subtree.
|
|
940
|
+
*/
|
|
941
|
+
function visit(value) {
|
|
942
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
943
|
+
return;
|
|
944
|
+
seen.add(value);
|
|
945
|
+
const candidate = /** @type {Record<string, unknown>} */ (value);
|
|
946
|
+
const provenance = candidate.sourceProvenance;
|
|
947
|
+
const origin = isPlainObject(provenance) ? provenance.origin : undefined;
|
|
948
|
+
if (isPlainObject(origin) && origin.kind == "source")
|
|
949
|
+
origin.sourceId = sourceId;
|
|
950
|
+
for (const child of Object.values(candidate))
|
|
951
|
+
visit(child);
|
|
952
|
+
}
|
|
953
|
+
visit(module);
|
|
954
|
+
for (const node of module.provenance.nodes) {
|
|
955
|
+
if (node.origin.kind == "source")
|
|
956
|
+
node.origin.sourceId = sourceId;
|
|
957
|
+
}
|
|
958
|
+
module.provenance.sources = sources;
|
|
959
|
+
}
|
|
960
|
+
/**
|
|
961
|
+
* Reports whether a candidate is a direct plain object.
|
|
962
|
+
* @param {unknown} value - Candidate object.
|
|
963
|
+
* @returns {value is Record<string, unknown>} Whether the value is a plain object.
|
|
964
|
+
*/
|
|
965
|
+
function isPlainObject(value) {
|
|
966
|
+
return Boolean(value) && typeof value == "object" && !Array.isArray(value) && Object.getPrototypeOf(value) == Object.prototype;
|
|
967
|
+
}
|
|
968
|
+
/**
|
|
969
|
+
* Reads a value whose map key was validated earlier in program assembly.
|
|
970
|
+
* @template T
|
|
971
|
+
* @param {Map<string, T>} map - Map with a previously validated key.
|
|
972
|
+
* @param {string} key - Required key.
|
|
973
|
+
* @returns {T} Stored value.
|
|
974
|
+
*/
|
|
975
|
+
function requiredMapValue(map, key) {
|
|
976
|
+
const value = map.get(key);
|
|
977
|
+
if (value === undefined)
|
|
978
|
+
throw new Error(`Missing validated map value '${key}'.`);
|
|
979
|
+
return value;
|
|
980
|
+
}
|
|
981
|
+
/**
|
|
982
|
+
* Raises a stable malformed program request diagnostic.
|
|
983
|
+
* @param {string} message - Stable request failure detail.
|
|
984
|
+
* @returns {never} Always throws.
|
|
985
|
+
*/
|
|
986
|
+
function invalidProgram(message) {
|
|
987
|
+
throw new SemantifoldDiagnostic({ code: "INVALID_PROGRAM", language: "program", message });
|
|
988
|
+
}
|
|
989
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3JhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9mcm9udGVuZHMvcHJvZ3JhbS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGFBQWEsQ0FBQTtBQUN4QyxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQTtBQUNwRCxPQUFPLEVBQUMscUJBQXFCLEVBQUUsZUFBZSxFQUFFLHFCQUFxQixFQUFFLGVBQWUsRUFBQyxNQUFNLGtCQUFrQixDQUFBO0FBQy9HLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQ3hELE9BQU8sRUFBQyw0QkFBNEIsRUFBQyxNQUFNLDZCQUE2QixDQUFBO0FBQ3hFLE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUN0RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUM5RCxPQUFPLEVBQUMsMkJBQTJCLEVBQUUsb0JBQW9CLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUN6RixPQUFPLEVBQ0wseUJBQXlCLEVBQUUsMEJBQTBCLEVBQUUsNkJBQTZCLEVBQUUsb0JBQW9CLEVBQzNHLE1BQU0sc0JBQXNCLENBQUE7QUFDN0IsT0FBTyxFQUFDLGlDQUFpQyxFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDNUUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sV0FBVyxDQUFBO0FBQzNDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLFVBQVUsQ0FBQTtBQUN6QyxPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxXQUFXLENBQUE7QUFFM0MsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBQ3JGLE1BQU0sZUFB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QUFRLENBQUE7SUFDbkUsQ0FBQztJQUNELE1BQU0sQ0FBQyxVQUFVLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQTtBQUNyQyxDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILFNBQVMsYUFBYSxDQUFDLEtBQUs7SUFDMUIsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksT0FBTyxLQUFLLElBQUksUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxTQUFTLENBQUE7QUFDaEksQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsZ0JBQWdCLENBQUMsR0FBRyxFQUFFLEdBQUc7SUFDaEMsTUFBTSxLQUFLLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtJQUUxQixJQUFJLEtBQUssS0FBSyxTQUFTO1FBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyxnQ0FBZ0MsR0FBRyxJQUFJLENBQUMsQ0FBQTtJQUVqRixPQUFPLEtBQUssQ0FBQTtBQUNkLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBUyxjQUFjLENBQUMsT0FBTztJQUM3QixNQUFNLElBQUkscUJBQXFCLENBQUMsRUFBQyxJQUFJLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUMsQ0FBQyxDQUFBO0FBQzFGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtpc0RlbnNlQXJyYXl9IGZyb20gXCIuLi9hcnJheS5qc1wiXG5pbXBvcnQge2lzU2FmZVNvdXJjZVBhdGh9IGZyb20gXCIuLi9hcnRpZmFjdC1wYXRoLmpzXCJcbmltcG9ydCB7U2VtYW50aWZvbGREaWFnbm9zdGljLCBzZW1hbnRpY0ZhaWx1cmUsIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eSwgdW5zdXBwb3J0ZWRSb2xlfSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2xhbmd1YWdlUmVnaXN0cnl9IGZyb20gXCIuLi9sYW5ndWFnZS1yZWdpc3RyeS5qc1wiXG5pbXBvcnQge25vcm1hbGl6ZUNhcGFiaWxpdHlBdXRob3JpdHl9IGZyb20gXCIuLi9zZW1hbnRpYy9jYXBhYmlsaXRpZXMuanNcIlxuaW1wb3J0IHttb2R1bGVMb2NhdGlvbn0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7YW5ub3RhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy9wcm92ZW5hbmNlLmpzXCJcbmltcG9ydCB7bW9kdWxlVW5jaGVja2VkRXJyb3JFZmZlY3RzLCB2YWxpZGF0ZVBhcnNlZE1vZHVsZX0gZnJvbSBcIi4uL3NlbWFudGljL3ZhbGlkYXRlLmpzXCJcbmltcG9ydCB7XG4gIGZhY2FkZUNhcGFiaWxpdHlBdXRob3JpdHksIHJlc29sdmVTdGRsaWJGYWNhZGVDbG9zdXJlLCBzdGRsaWJGYWNhZGVQcm9ncmFtRGVzY3JpcHRvciwgc3RkbGliRmFjYWRlUmVnaXN0cnlcbn0gZnJvbSBcIi4uL3N0ZGxpYi1mYWNhZGVzLmpzXCJcbmltcG9ydCB7aW5zcGVjdEphdmFTY3JpcHRUeXBlU2NyaXB0TW9kdWxlfSBmcm9tIFwiLi9qYXZhc2NyaXB0LXR5cGVzY3JpcHQuanNcIlxuaW1wb3J0IHtpbnNwZWN0SmF2YU1vZHVsZX0gZnJvbSBcIi4vamF2YS5qc1wiXG5pbXBvcnQge2luc3BlY3RQaHBNb2R1bGV9IGZyb20gXCIuL3BocC5qc1wiXG5pbXBvcnQge2luc3BlY3RSdWJ5TW9kdWxlfSBmcm9tIFwiLi9ydWJ5LmpzXCJcblxuY29uc3QgcHJvZ3JhbUxhbmd1YWdlcyA9IG5ldyBTZXQoW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiXSlcbmNvbnN0IG1vZHVsZUlkUGF0dGVybiA9IC9eW2Etel1bYS16MC05X10qKD86Wy4tXVthLXpdW2EtejAtOV9dKikqJC91XG5cbi8qKiBAdHlwZWRlZiB7e2ZhY2FkZT86IGltcG9ydChcIi4uL3N0ZGxpYi1mYWNhZGVzLmpzXCIpLlN0ZGxpYkZhY2FkZVJlY29yZCwgZmlsZW5hbWU6IHN0cmluZywgaWQ6IHN0cmluZywgbGFuZ3VhZ2U6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2UsIG93bmVyc2hpcDogXCJhcHBsaWNhdGlvblwiIHwgXCJmYWNhZGVcIiwgc291cmNlOiBzdHJpbmd9fSBQcm9ncmFtU291cmNlICovXG4vKiogQHR5cGVkZWYge3tkZWNsYXJhdGlvbkxvY2F0aW9uPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIGZhY2FkZT86IGltcG9ydChcIi4uL3N0ZGxpYi1mYWNhZGVzLmpzXCIpLlN0ZGxpYkZhY2FkZVJlY29yZCwgaW1wb3J0ZWROYW1lOiBzdHJpbmcsIGltcG9ydGVkTmFtZUxvY2F0aW9uPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIGxvY2FsTmFtZTogc3RyaW5nLCBsb2NhbE5hbWVMb2NhdGlvbj86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIG5hbWVzcGFjZT86IGJvb2xlYW4sIHBhdGhMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNwZWNpZmllcjogc3RyaW5nLCBzdGRsaWJDYW5kaWRhdGU/OiB0cnVlLCB0eXBlT25seTogYm9vbGVhbn19IFByb2dyYW1JbXBvcnRSZXF1ZXN0ICovXG4vKiogQHR5cGVkZWYge3tpbXBvcnRlZE5hbWU6IHN0cmluZywgbG9jYWxOYW1lOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgbmF0aXZlTmFtZTogc3RyaW5nLCBzeW1ib2xLaW5kOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0RlY2xhcmF0aW9uS2luZCwgdHlwZU9ubHk6IGJvb2xlYW59fSBQcm9ncmFtTmF0aXZlQmluZGluZyAqL1xuLyoqIEB0eXBlZGVmIHt7aW1wb3J0czogUHJvZ3JhbUltcG9ydFJlcXVlc3RbXSwgZXhwb3J0czoge2RlY2xhcmF0aW9uTG9jYXRpb24/OiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgZXhwb3J0ZWROYW1lOiBzdHJpbmcsIGV4cG9ydGVkTmFtZUxvY2F0aW9uPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIGxvY2FsTmFtZTogc3RyaW5nLCBsb2NhbE5hbWVMb2NhdGlvbj86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHN5bWJvbEtpbmQ/OiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0RlY2xhcmF0aW9uS2luZCwgdHlwZU9ubHk6IGJvb2xlYW59W10sIGJpbmRpbmdzPzogUHJvZ3JhbU5hdGl2ZUJpbmRpbmdbXSwgbmF0aXZlTmFtZT86IHN0cmluZywgbmF0aXZlUmVmZXJlbmNlcz86IHtmb3JtOiBcImNvbnN0cnVjdG9yLWNhbGxcIiB8IFwicmVjZWl2ZXItY2FsbFwiIHwgXCJ1bnF1YWxpZmllZC1jYWxsXCIsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgbmF0aXZlTW9kdWxlOiBzdHJpbmcsIHN5bWJvbDogc3RyaW5nfVtdfX0gUHJvZ3JhbUhlYWRlciAqL1xuXG4vKipcbiAqIFBhcnNlcyBhbiBleHBsaWNpdCBjYWxsZXItc3VwcGxpZWQgbXVsdGktc291cmNlIHByb2dyYW0gd2l0aG91dCBmaWxlc3lzdGVtIGRpc2NvdmVyeS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBpbnB1dCAtIFByb2dyYW0gcGFyc2UgcmVxdWVzdC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5lbnRyeU1vZHVsZSAtIFNvbGUgZW50cnkgbW9kdWxlIGlkZW50aXR5LlxuICogQHBhcmFtIHt7ZmlsZW5hbWU6IHN0cmluZywgaWQ6IHN0cmluZywgbGFuZ3VhZ2U6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2UsIHNvdXJjZTogc3RyaW5nfVtdfSBpbnB1dC5zb3VyY2VzIC0gQ29tcGxldGUgc291cmNlIHNldC5cbiAqIEBwYXJhbSB7UmVhZG9ubHk8aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2FwYWJpbGl0eUF1dGhvcml0eT4gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DYXBhYmlsaXR5QXV0aG9yaXR5SW5wdXR9IFtpbnB1dC5jYXBhYmlsaXR5QXV0aG9yaXR5XSAtIEV4cGxpY2l0IGNvbXBpbGVyIGF1dGhvcml0eS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW19IFJlc29sdmVkIHNlbWFudGljIHByb2dyYW0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVByb2dyYW1Tb3VyY2UoaW5wdXQpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGlucHV0KSB8fCAhaXNEZW5zZUFycmF5KGlucHV0LnNvdXJjZXMpIHx8IGlucHV0LnNvdXJjZXMubGVuZ3RoID09IDAgfHxcbiAgICB0eXBlb2YgaW5wdXQuZW50cnlNb2R1bGUgIT0gXCJzdHJpbmdcIikgaW52YWxpZFByb2dyYW0oXCJQcm9ncmFtIHBhcnNpbmcgcmVxdWlyZXMgYSBub24tZW1wdHkgb3JkZXJlZCBzb3VyY2Ugc2V0IGFuZCBlbnRyeSBtb2R1bGUuXCIpXG5cbiAgY29uc3QgYXBwbGljYXRpb25Tb3VyY2VzID0gaW5wdXQuc291cmNlcy5tYXAoKHNvdXJjZSwgaW5kZXgpID0+IHZhbGlkYXRlU291cmNlKHNvdXJjZSwgaW5kZXgpKVxuICBjb25zdCByZXF1ZXN0ZWRBdXRob3JpdHkgPSBub3JtYWxpemVDYXBhYmlsaXR5QXV0aG9yaXR5KGlucHV0LmNhcGFiaWxpdHlBdXRob3JpdHkpXG4gIGNvbnN0IHNvdXJjZUxhbmd1YWdlcyA9IG5ldyBTZXQoYXBwbGljYXRpb25Tb3VyY2VzLm1hcCgoe2xhbmd1YWdlfSkgPT4gbGFuZ3VhZ2UpKVxuXG4gIGlmIChzb3VyY2VMYW5ndWFnZXMuc2l6ZSAhPSAxKSB7XG4gICAgc2VtYW50aWNGYWlsdXJlKGFwcGxpY2F0aW9uU291cmNlc1swXS5sYW5ndWFnZSwgXCJNSVhFRF9TT1VSQ0VfTEFOR1VBR0VTXCIsIFwiQSBzZW1hbnRpYyBwcm9ncmFtIG11c3QgdXNlIG9uZSBzb3VyY2UtbGFuZ3VhZ2UgY29tcGF0aWJpbGl0eSBwcm9maWxlLlwiLCB1bmRlZmluZWQpXG4gIH1cbiAgaWYgKHJlcXVlc3RlZEF1dGhvcml0eSAmJiAhbGFuZ3VhZ2VSZWdpc3RyeS5yZWNvcmQoYXBwbGljYXRpb25Tb3VyY2VzWzBdLmxhbmd1YWdlKS5mZWF0dXJlcy5lZmZlY3RmdWxDYXBhYmlsaXRpZXNBbmRSZXNvdXJjZXMpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkoYXBwbGljYXRpb25Tb3VyY2VzWzBdLmxhbmd1YWdlLCBcIlRhc2sgMDM0IGVmZmVjdGZ1bCBjYXBhYmlsaXRpZXMgYW5kIG93bmVkIHJlc291cmNlc1wiLFxuICAgICAgbW9kdWxlTG9jYXRpb24oYXBwbGljYXRpb25Tb3VyY2VzWzBdLmZpbGVuYW1lLCBhcHBsaWNhdGlvblNvdXJjZXNbMF0uc291cmNlKSlcbiAgfVxuICBjb25zdCBieUlkID0gbmV3IE1hcCgpXG4gIGNvbnN0IGJ5RmlsZW5hbWUgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBhcHBsaWNhdGlvblNvdXJjZXMpIHtcbiAgICBpZiAoYnlJZC5oYXMoc291cmNlLmlkKSkgc2VtYW50aWNGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJEVVBMSUNBVEVfTU9EVUxFXCIsIGBEdXBsaWNhdGUgbW9kdWxlIGlkZW50aXR5ICcke3NvdXJjZS5pZH0nLmAsIHVuZGVmaW5lZClcbiAgICBpZiAoYnlGaWxlbmFtZS5oYXMoc291cmNlLmZpbGVuYW1lKSkgc2VtYW50aWNGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJEVVBMSUNBVEVfTU9EVUxFXCIsIGBEdXBsaWNhdGUgbW9kdWxlIGZpbGVuYW1lICcke3NvdXJjZS5maWxlbmFtZX0nLmAsIHVuZGVmaW5lZClcbiAgICBieUlkLnNldChzb3VyY2UuaWQsIHNvdXJjZSlcbiAgICBieUZpbGVuYW1lLnNldChzb3VyY2UuZmlsZW5hbWUsIHNvdXJjZSlcbiAgfVxuICBpZiAoIWJ5SWQuaGFzKGlucHV0LmVudHJ5TW9kdWxlKSkge1xuICAgIHNlbWFudGljRmFpbHVyZShhcHBsaWNhdGlvblNvdXJjZXNbMF0ubGFuZ3VhZ2UsIFwiSU5WQUxJRF9FTlRSWV9NT0RVTEVcIiwgYFVua25vd24gZW50cnkgbW9kdWxlICcke2lucHV0LmVudHJ5TW9kdWxlfScuYCwgdW5kZWZpbmVkKVxuICB9XG5cbiAgY29uc3QgaGVhZGVycyA9IG5ldyBNYXAoYXBwbGljYXRpb25Tb3VyY2VzLm1hcCgoc291cmNlKSA9PiBbc291cmNlLmlkLCBpbnNwZWN0U291cmNlKHNvdXJjZSldKSlcbiAgY29uc3QgZmFjYWRlUm9vdHMgPSByZXNvbHZlRmFjYWRlSW1wb3J0cyhhcHBsaWNhdGlvblNvdXJjZXMsIGhlYWRlcnMpXG4gIGNvbnN0IGZhY2FkZVJlY29yZHMgPSByZXNvbHZlU3RkbGliRmFjYWRlQ2xvc3VyZShmYWNhZGVSb290cylcblxuICBpZiAoZmFjYWRlUmVjb3Jkcy5sZW5ndGggPiAwICYmIHJlcXVlc3RlZEF1dGhvcml0eSkge1xuICAgIGNvbnN0IGxvY2F0ZWQgPSBhcHBsaWNhdGlvblNvdXJjZXMuZmxhdE1hcCgoc291cmNlKSA9PiByZXF1aXJlZE1hcFZhbHVlKGhlYWRlcnMsIHNvdXJjZS5pZCkuaW1wb3J0cylcbiAgICAgIC5maW5kKCh7ZmFjYWRlfSkgPT4gZmFjYWRlKT8ubG9jYXRpb25cblxuICAgIGZhY2FkZUZhaWx1cmUoYXBwbGljYXRpb25Tb3VyY2VzWzBdLmxhbmd1YWdlLCBcIlNURExJQl9GQUNBREVfQVVUSE9SSVRZX0ZPUkdFRFwiLFxuICAgICAgXCJQcm9ncmFtcyByZXNvbHZlZCB0aHJvdWdoIGNvbXBpbGVyLW93bmVkIGZhY2FkZXMgY2Fubm90IHN1cHBseSB0aGVpciBvd24gY2Fub25pY2FsIGNhcGFiaWxpdHkgYXV0aG9yaXR5LlwiLCBsb2NhdGVkKVxuICB9XG4gIGNvbnN0IGZhY2FkZUF1dGhvcml0eSA9IGZhY2FkZUNhcGFiaWxpdHlBdXRob3JpdHkoZmFjYWRlUmVjb3JkcylcbiAgY29uc3QgYXV0aG9yaXR5ID0gcmVxdWVzdGVkQXV0aG9yaXR5ID8/IChmYWNhZGVBdXRob3JpdHkgPyBub3JtYWxpemVDYXBhYmlsaXR5QXV0aG9yaXR5KGZhY2FkZUF1dGhvcml0eS5pbnB1dCkgOiB1bmRlZmluZWQpXG4gIGNvbnN0IGZhY2FkZVNvdXJjZXMgPSBmYWNhZGVSZWNvcmRzLm1hcCgoZmFjYWRlKSA9PiAvKiogQHR5cGUge1Byb2dyYW1Tb3VyY2V9ICovICh7XG4gICAgZmFjYWRlLFxuICAgIGZpbGVuYW1lOiBmYWNhZGUuc291cmNlLmZpbGVuYW1lLFxuICAgIGlkOiBmYWNhZGUuc291cmNlLmlkLFxuICAgIGxhbmd1YWdlOiBmYWNhZGUubGFuZ3VhZ2UsXG4gICAgb3duZXJzaGlwOiBcImZhY2FkZVwiLFxuICAgIHNvdXJjZTogZmFjYWRlLnNvdXJjZS5jb250ZW50XG4gIH0pKVxuXG4gIHZhbGlkYXRlRmFjYWRlQ29sbGlzaW9ucyhhcHBsaWNhdGlvblNvdXJjZXMsIGhlYWRlcnMsIGZhY2FkZVNvdXJjZXMpXG4gIGNvbnN0IHNvdXJjZXMgPSBbLi4uYXBwbGljYXRpb25Tb3VyY2VzLCAuLi5mYWNhZGVTb3VyY2VzXVxuXG4gIGZvciAoY29uc3Qgc291cmNlIG9mIGZhY2FkZVNvdXJjZXMpIHtcbiAgICBieUlkLnNldChzb3VyY2UuaWQsIHNvdXJjZSlcbiAgICBieUZpbGVuYW1lLnNldChzb3VyY2UuZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBoZWFkZXJzLnNldChzb3VyY2UuaWQsIGluc3BlY3RTb3VyY2Uoc291cmNlKSlcbiAgfVxuICBjb25zdCByZWdpc3RlcmVkU291cmNlcyA9IHNvdXJjZXMubWFwKChzb3VyY2UsIGluZGV4KSA9PiAoe1xuICAgIGNvbnRlbnQ6IHNvdXJjZS5zb3VyY2UsXG4gICAgZmlsZW5hbWU6IHNvdXJjZS5maWxlbmFtZSxcbiAgICBpZDogYHNvdXJjZToke2luZGV4fWAsXG4gICAgbGFuZ3VhZ2U6IHNvdXJjZS5sYW5ndWFnZSxcbiAgICBvd25lcnNoaXA6IHNvdXJjZS5vd25lcnNoaXBcbiAgfSkpXG4gIGNvbnN0IHNvdXJjZUlkcyA9IG5ldyBNYXAoc291cmNlcy5tYXAoKHNvdXJjZSwgaW5kZXgpID0+IFtzb3VyY2UuaWQsIGBzb3VyY2U6JHtpbmRleH1gXSkpXG5cbiAgdmFsaWRhdGVOYXRpdmVNb2R1bGVJZGVudGl0aWVzKHNvdXJjZXMsIGhlYWRlcnMpXG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywge3NvdXJjZTogdHlwZW9mIHNvdXJjZXNbbnVtYmVyXSwgcmVxdWVzdHM6IChSZXR1cm5UeXBlPHR5cGVvZiBpbnNwZWN0U291cmNlPltcImltcG9ydHNcIl1bbnVtYmVyXSAmIHttb2R1bGVJZDogc3RyaW5nfSlbXX0+fSAqL1xuICBjb25zdCBncmFwaCA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3Qgc291cmNlIG9mIHNvdXJjZXMpIHtcbiAgICBjb25zdCByZXF1ZXN0cyA9IHJlcXVpcmVkTWFwVmFsdWUoaGVhZGVycywgc291cmNlLmlkKS5pbXBvcnRzLm1hcCgocmVxdWVzdCkgPT4gKHtcbiAgICAgIC4uLnJlcXVlc3QsXG4gICAgICBtb2R1bGVJZDogcmVxdWVzdC5mYWNhZGU/LnNvdXJjZS5pZCA/PyByZXNvbHZlSW1wb3J0TW9kdWxlKHNvdXJjZSwgcmVxdWVzdC5zcGVjaWZpZXIsIHJlcXVlc3QucGF0aExvY2F0aW9uLCBieUZpbGVuYW1lLCBoZWFkZXJzKVxuICAgIH0pKVxuXG4gICAgZ3JhcGguc2V0KHNvdXJjZS5pZCwge3JlcXVlc3RzLCBzb3VyY2V9KVxuICB9XG4gIGNvbnN0IG9yZGVyZWRJZHMgPSB0b3BvbG9naWNhbE9yZGVyKHNvdXJjZXMsIGdyYXBoKVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZT59ICovXG4gIGNvbnN0IHBhcnNlZCA9IG5ldyBNYXAoKVxuICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFNldDxzdHJpbmc+Pn0gKi9cbiAgY29uc3QgY2FsbEVmZmVjdHNCeURlY2xhcmF0aW9uSWQgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IG1vZHVsZUlkIG9mIG9yZGVyZWRJZHMpIHtcbiAgICBjb25zdCB7cmVxdWVzdHMsIHNvdXJjZX0gPSByZXF1aXJlZE1hcFZhbHVlKGdyYXBoLCBtb2R1bGVJZClcbiAgICBjb25zdCBzb3VyY2VJZCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoc291cmNlSWRzLmdldChzb3VyY2UuaWQpKVxuICAgIGNvbnN0IGhlYWRlciA9IHJlcXVpcmVkTWFwVmFsdWUoaGVhZGVycywgbW9kdWxlSWQpXG4gICAgY29uc3QgbG9jYWxOYW1lcyA9IG5ldyBTZXQoKVxuICAgIGNvbnN0IHZpc2libGVGdW5jdGlvbnMgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlQ2FsbEVmZmVjdHMgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlUmVjb3Jkc0J5TmFtZSA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IHZpc2libGVWYWx1ZVJlY29yZHNCeU5hbWUgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlUmVjb3Jkc0J5SWQgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlQ2xhc3Nlc0J5TmFtZSA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IHZpc2libGVDbGFzc2VzQnlJZCA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IHZpc2libGVFcnJvcnNCeU5hbWUgPSBuZXcgTWFwKClcbiAgICBjb25zdCB2aXNpYmxlRXJyb3JzQnlJZCA9IG5ldyBNYXAoKVxuICAgIGNvbnN0IGNvbnN1bWVkQmluZGluZ3MgPSBuZXcgU2V0KClcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljSW1wb3J0W119ICovXG4gICAgY29uc3QgaW1wb3J0cyA9IFtdXG5cbiAgICBpZiAoIXNvdXJjZS5mYWNhZGUgJiYgYXV0aG9yaXR5KSB7XG4gICAgICBjb25zdCBmYWlsdXJlTmFtZXMgPSBuZXcgU2V0KGhlYWRlci5pbXBvcnRzLmZpbHRlcigoe2ZhY2FkZX0pID0+IGZhY2FkZSkuZmxhdE1hcCgoe2ZhY2FkZX0pID0+XG4gICAgICAgIGZhY2FkZT8ucHVibGljRGVjbGFyYXRpb25zLmZsYXRNYXAoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5raW5kID09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gZGVjbGFyYXRpb24uZmFpbHVyZXNcbiAgICAgICAgICA6IFsuLi5kZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5mYWlsdXJlcywgLi4uZGVjbGFyYXRpb24ubWV0aG9kcy5mbGF0TWFwKCh7ZmFpbHVyZXN9KSA9PiBmYWlsdXJlcyldKSA/PyBbXSkpXG5cbiAgICAgIGZvciAoY29uc3QgZmFpbHVyZSBvZiBhdXRob3JpdHkuY2FwYWJpbGl0aWVzLmZsYXRNYXAoKHtmYWlsdXJlc30pID0+IGZhaWx1cmVzKSkge1xuICAgICAgICBpZiAoIWZhaWx1cmVOYW1lcy5oYXMoZmFpbHVyZS5uYW1lKSkgY29udGludWVcbiAgICAgICAgY29uc3QgZGVjbGFyYXRpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChmYWlsdXJlKSlcblxuICAgICAgICB2aXNpYmxlRXJyb3JzQnlOYW1lLnNldChmYWlsdXJlLm5hbWUsIGRlY2xhcmF0aW9uKVxuICAgICAgICB2aXNpYmxlRXJyb3JzQnlJZC5zZXQoZmFpbHVyZS5pZCwgZGVjbGFyYXRpb24pXG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCByZXF1ZXN0IG9mIHJlcXVlc3RzKSB7XG4gICAgICBjb25zdCBkZXBlbmRlbmN5ID0gcGFyc2VkLmdldChyZXF1ZXN0Lm1vZHVsZUlkKVxuXG4gICAgICBpZiAoIWRlcGVuZGVuY3kpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBEZXBlbmRlbmN5ICcke3JlcXVlc3QubW9kdWxlSWR9JyB3YXMgbm90IHBhcnNlZCBiZWZvcmUgJyR7c291cmNlLmlkfScuYClcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRlcGVuZGVuY3lIZWFkZXIgPSByZXF1aXJlZE1hcFZhbHVlKGhlYWRlcnMsIHJlcXVlc3QubW9kdWxlSWQpXG4gICAgICBjb25zdCBuYXRpdmVCaW5kaW5nUHJlZml4ID0gcmVxdWVzdC5mYWNhZGU/Lm5hdGl2ZU1vZHVsZXMuZmluZCgoe2lkZW50aXR5fSkgPT4gaWRlbnRpdHkgPT0gcmVxdWVzdC5zcGVjaWZpZXIpPy5pZGVudGl0eSA/P1xuICAgICAgICBkZXBlbmRlbmN5SGVhZGVyLm5hdGl2ZU5hbWVcbiAgICAgIGNvbnN0IG5hdGl2ZUJpbmRpbmdzID0gc291cmNlLmxhbmd1YWdlID09IFwicGhwXCIgJiYgcmVxdWVzdC5uYW1lc3BhY2VcbiAgICAgICAgPyAoaGVhZGVyLmJpbmRpbmdzID8/IFtdKS5maWx0ZXIoKHtuYXRpdmVOYW1lfSkgPT4gbmF0aXZlTmFtZS5zdGFydHNXaXRoKGAke25hdGl2ZUJpbmRpbmdQcmVmaXh9XFxcXGApKVxuICAgICAgICA6IFtdXG4gICAgICBjb25zdCBzZWxlY3RlZEV4cG9ydHMgPSByZXF1ZXN0Lm5hbWVzcGFjZSAmJiBzb3VyY2UubGFuZ3VhZ2UgPT0gXCJwaHBcIlxuICAgICAgICA/IGRlcGVuZGVuY3kuZXhwb3J0cy5maWx0ZXIoKHtleHBvcnRlZE5hbWV9KSA9PiBuYXRpdmVCaW5kaW5ncy5zb21lKCh7aW1wb3J0ZWROYW1lfSkgPT4gaW1wb3J0ZWROYW1lID09IGV4cG9ydGVkTmFtZSkpXG4gICAgICAgIDogcmVxdWVzdC5uYW1lc3BhY2VcbiAgICAgICAgICA/IGRlcGVuZGVuY3kuZXhwb3J0c1xuICAgICAgICA6IGRlcGVuZGVuY3kuZXhwb3J0cy5maWx0ZXIoKHtleHBvcnRlZE5hbWV9KSA9PiBleHBvcnRlZE5hbWUgPT0gcmVxdWVzdC5pbXBvcnRlZE5hbWUpXG5cbiAgICAgIGlmIChzZWxlY3RlZEV4cG9ydHMubGVuZ3RoID09IDApIHtcbiAgICAgICAgc2VtYW50aWNGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJVTlJFU09MVkVEX0lNUE9SVFwiLCByZXF1ZXN0Lm5hbWVzcGFjZVxuICAgICAgICAgID8gYEltcG9ydGVkIG1vZHVsZSAnJHtyZXF1ZXN0Lm1vZHVsZUlkfScgaGFzIG5vIGV4cGxpY2l0bHkgYm91bmQgZXhwb3J0cy5gXG4gICAgICAgICAgOiBgTW9kdWxlICcke3JlcXVlc3QubW9kdWxlSWR9JyBkb2VzIG5vdCBleHBvcnQgJyR7cmVxdWVzdC5pbXBvcnRlZE5hbWV9Jy5gLCByZXF1ZXN0LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgZm9yIChjb25zdCBleHBvcnRlZCBvZiBzZWxlY3RlZEV4cG9ydHMpIHtcbiAgICAgICAgY29uc3QgbmF0aXZlQmluZGluZyA9IG5hdGl2ZUJpbmRpbmdzLmZpbmQoKHtpbXBvcnRlZE5hbWV9KSA9PiBpbXBvcnRlZE5hbWUgPT0gZXhwb3J0ZWQuZXhwb3J0ZWROYW1lKVxuICAgICAgICBjb25zdCBsb2NhbE5hbWUgPSBuYXRpdmVCaW5kaW5nPy5sb2NhbE5hbWUgPz8gKHJlcXVlc3QubmFtZXNwYWNlXG4gICAgICAgICAgPyBxdWFsaWZpZWRJbXBvcnROYW1lKHNvdXJjZS5sYW5ndWFnZSwgZGVwZW5kZW5jeUhlYWRlci5uYXRpdmVOYW1lLCBleHBvcnRlZClcbiAgICAgICAgICA6IHJlcXVlc3QubG9jYWxOYW1lXG4gICAgICAgIClcbiAgICAgICAgY29uc3QgaW1wb3J0TG9jYXRpb24gPSBuYXRpdmVCaW5kaW5nPy5sb2NhdGlvbiA/PyByZXF1ZXN0LmxvY2F0aW9uXG5cbiAgICAgICAgaWYgKGxvY2FsTmFtZXMuaGFzKGxvY2FsTmFtZSkpIHtcbiAgICAgICAgICBzZW1hbnRpY0ZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIkRVUExJQ0FURV9JTVBPUlRfQklORElOR1wiLCBgRHVwbGljYXRlIGltcG9ydCBiaW5kaW5nICcke2xvY2FsTmFtZX0nLmAsIGltcG9ydExvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIGxvY2FsTmFtZXMuYWRkKGxvY2FsTmFtZSlcbiAgICAgICAgaWYgKG5hdGl2ZUJpbmRpbmcgJiYgbmF0aXZlQmluZGluZy5zeW1ib2xLaW5kICE9IGV4cG9ydGVkLnN5bWJvbEtpbmQgJiZcbiAgICAgICAgICAhKG5hdGl2ZUJpbmRpbmcuc3ltYm9sS2luZCA9PSBcInJlY29yZFwiICYmIGV4cG9ydGVkLnN5bWJvbEtpbmQgPT0gXCJlcnJvclwiKSkge1xuICAgICAgICAgIHNlbWFudGljRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiSU1QT1JUX0tJTkRfTUlTTUFUQ0hcIiwgYEltcG9ydCAnJHtuYXRpdmVCaW5kaW5nLmltcG9ydGVkTmFtZX0nIGhhcyB0aGUgd3JvbmcgZGVjbGFyYXRpb24ga2luZC5gLCBpbXBvcnRMb2NhdGlvbilcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVxdWVzdC50eXBlT25seSAmJiBleHBvcnRlZC5zeW1ib2xLaW5kICE9IFwicmVjb3JkXCIpIHtcbiAgICAgICAgICBzZW1hbnRpY0ZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIklNUE9SVF9LSU5EX01JU01BVENIXCIsIGBUeXBlIGltcG9ydCAnJHtyZXF1ZXN0LmltcG9ydGVkTmFtZX0nIGRvZXMgbm90IG5hbWUgYSByZWNvcmQuYCwgaW1wb3J0TG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgICAgaWYgKG5hdGl2ZUJpbmRpbmcpIGNvbnN1bWVkQmluZGluZ3MuYWRkKG5hdGl2ZUJpbmRpbmcpXG4gICAgICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gZGVjbGFyYXRpb25Gb3IoZGVwZW5kZW5jeSwgZXhwb3J0ZWQpXG4gICAgICAgIGNvbnN0IHR5cGVPbmx5ID0gbmF0aXZlQmluZGluZz8udHlwZU9ubHkgPz8gcmVxdWVzdC50eXBlT25seVxuXG4gICAgICAgIGlmIChleHBvcnRlZC5zeW1ib2xLaW5kID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgIHZpc2libGVGdW5jdGlvbnMuc2V0KGxvY2FsTmFtZSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSAqLyAoZGVjbGFyYXRpb24pKVxuICAgICAgICAgIHZpc2libGVDYWxsRWZmZWN0cy5zZXQobG9jYWxOYW1lLCBuZXcgU2V0KGNhbGxFZmZlY3RzQnlEZWNsYXJhdGlvbklkLmdldChleHBvcnRlZC5kZWNsYXJhdGlvbklkKSA/PyBbXSkpXG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoZXhwb3J0ZWQuc3ltYm9sS2luZCA9PSBcInJlY29yZFwiKSB7XG4gICAgICAgICAgY29uc3QgcmVjb3JkID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gKi8gKGRlY2xhcmF0aW9uKVxuXG4gICAgICAgICAgdmlzaWJsZVJlY29yZHNCeU5hbWUuc2V0KGxvY2FsTmFtZSwgcmVjb3JkKVxuICAgICAgICAgIGlmICghdHlwZU9ubHkpIHZpc2libGVWYWx1ZVJlY29yZHNCeU5hbWUuc2V0KGxvY2FsTmFtZSwgcmVjb3JkKVxuICAgICAgICAgIHZpc2libGVSZWNvcmRzQnlJZC5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyZWNvcmQuaWQpLCByZWNvcmQpXG4gICAgICAgIH0gZWxzZSBpZiAoZXhwb3J0ZWQuc3ltYm9sS2luZCA9PSBcImNsYXNzXCIpIHtcbiAgICAgICAgICBjb25zdCBkZWNsYXJhdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gKi8gKGRlY2xhcmF0aW9uRm9yKGRlcGVuZGVuY3ksIGV4cG9ydGVkKSlcblxuICAgICAgICAgIHZpc2libGVDbGFzc2VzQnlOYW1lLnNldChsb2NhbE5hbWUsIGRlY2xhcmF0aW9uKVxuICAgICAgICAgIHZpc2libGVDbGFzc2VzQnlJZC5zZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGRlY2xhcmF0aW9uKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGVycm9yID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSAqLyAoZGVjbGFyYXRpb24pXG5cbiAgICAgICAgICB2aXNpYmxlRXJyb3JzQnlOYW1lLnNldChsb2NhbE5hbWUsIGVycm9yKVxuICAgICAgICAgIHZpc2libGVFcnJvcnNCeUlkLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGVycm9yLmlkKSwgZXJyb3IpXG4gICAgICAgIH1cbiAgICAgICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbj59ICovXG4gICAgICAgIGNvbnN0IHJhbmdlcyA9IHtcbiAgICAgICAgICBkZWNsYXJhdGlvbjogcmVxdWVzdC5kZWNsYXJhdGlvbkxvY2F0aW9uID8/IHJlcXVlc3QubG9jYXRpb24sXG4gICAgICAgICAgcGF0aDogcmVxdWVzdC5wYXRoTG9jYXRpb25cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcmVxdWVzdC5uYW1lc3BhY2UgfHwgbmF0aXZlQmluZGluZyB8fCByZXF1ZXN0LmZhY2FkZSkge1xuICAgICAgICAgIHJhbmdlcy5pbXBvcnRlZE5hbWUgPSBuYXRpdmVCaW5kaW5nPy5sb2NhdGlvbiA/PyByZXF1ZXN0LmltcG9ydGVkTmFtZUxvY2F0aW9uID8/IGltcG9ydExvY2F0aW9uXG4gICAgICAgICAgcmFuZ2VzLmxvY2FsTmFtZSA9IG5hdGl2ZUJpbmRpbmc/LmxvY2F0aW9uID8/IHJlcXVlc3QubG9jYWxOYW1lTG9jYXRpb24gPz8gaW1wb3J0TG9jYXRpb25cbiAgICAgICAgfVxuXG4gICAgICAgIGltcG9ydHMucHVzaCh7XG4gICAgICAgICAgZGVjbGFyYXRpb25JZDogZXhwb3J0ZWQuZGVjbGFyYXRpb25JZCxcbiAgICAgICAgICBpbXBvcnRlZE5hbWU6IGV4cG9ydGVkLmV4cG9ydGVkTmFtZSxcbiAgICAgICAgICBraW5kOiBcIkltcG9ydFwiLFxuICAgICAgICAgIGxvY2FsTmFtZSxcbiAgICAgICAgICBsb2NhdGlvbjogaW1wb3J0TG9jYXRpb24sXG4gICAgICAgICAgbW9kdWxlSWQ6IHJlcXVlc3QubW9kdWxlSWQsXG4gICAgICAgICAgLi4uKHJlcXVlc3QuZmFjYWRlID8ge3N0ZGxpYkZhY2FkZToge1xuICAgICAgICAgICAgZmFjYWRlSWRlbnRpdHk6IHJlcXVlc3QuZmFjYWRlLmlkZW50aXR5LFxuICAgICAgICAgICAgZmFjYWRlVmVyc2lvbjogcmVxdWVzdC5mYWNhZGUudmVyc2lvbixcbiAgICAgICAgICAgIG5hdGl2ZU1vZHVsZTogcmVxdWVzdC5zcGVjaWZpZXIsXG4gICAgICAgICAgICBuYXRpdmVTeW1ib2w6IGV4cG9ydGVkLmV4cG9ydGVkTmFtZSxcbiAgICAgICAgICAgIHNjaGVtYTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiU2VtYW50aWZvbGRTdGRsaWJGYWNhZGVSZXNvbHV0aW9uXCIpLFxuICAgICAgICAgICAgdmVyc2lvbjogLyoqIEB0eXBlIHtjb25zdH0gKi8gKDEpXG4gICAgICAgICAgfX0gOiB7fSksXG4gICAgICAgICAgc291cmNlUHJvdmVuYW5jZTogc291cmNlQXNzb2NpYXRpb24oaW1wb3J0TG9jYXRpb24sIHJhbmdlcywgc291cmNlSWQpLFxuICAgICAgICAgIHN5bWJvbEtpbmQ6IGV4cG9ydGVkLnN5bWJvbEtpbmQsXG4gICAgICAgICAgdHlwZU9ubHlcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG4gICAgY29uc3QgdW5jb25zdW1lZEJpbmRpbmcgPSAoaGVhZGVyLmJpbmRpbmdzID8/IFtdKS5maW5kKChiaW5kaW5nKSA9PiAhY29uc3VtZWRCaW5kaW5ncy5oYXMoYmluZGluZykpXG5cbiAgICBpZiAodW5jb25zdW1lZEJpbmRpbmcpIHtcbiAgICAgIHNlbWFudGljRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiVU5SRVNPTFZFRF9JTVBPUlRcIiwgYE5hdGl2ZSBpbXBvcnQgJyR7dW5jb25zdW1lZEJpbmRpbmcubmF0aXZlTmFtZX0nIGhhcyBubyBtYXRjaGluZyByZXF1aXJlZCBtb2R1bGUuYCwgdW5jb25zdW1lZEJpbmRpbmcubG9jYXRpb24pXG4gICAgfVxuXG4gICAgY29uc3QgZnJvbnRlbmQgPSAvKiogQHR5cGUgeyhpbnB1dDogb2JqZWN0KSA9PiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gKi8gKFxuICAgICAgbGFuZ3VhZ2VSZWdpc3RyeS5yZXNvbHZlKHNvdXJjZS5sYW5ndWFnZSwgXCJmcm9udGVuZFwiKSlcbiAgICBjb25zdCBmYWNhZGVNb2R1bGVzID0gbmV3IFNldChzb3VyY2UuZmFjYWRlPy5yZXF1aXJlbWVudHMubWFwKCh7bW9kdWxlfSkgPT4gbW9kdWxlKSA/PyBbXSlcbiAgICBjb25zdCBtb2R1bGVDYXBhYmlsaXRpZXMgPSByZXF1ZXN0ZWRBdXRob3JpdHk/LmNhcGFiaWxpdGllcyA/PyAoc291cmNlLmZhY2FkZT8ucmVxdWlyZW1lbnRzLmxlbmd0aFxuICAgICAgPyBhdXRob3JpdHk/Lm1vZHVsZXM/LmZpbHRlcigoe2lkZW50aXR5fSkgPT4gZmFjYWRlTW9kdWxlcy5oYXMoaWRlbnRpdHkpKS5mbGF0TWFwKCh7Y2FwYWJpbGl0aWVzfSkgPT4gY2FwYWJpbGl0aWVzKSA/P1xuICAgICAgICBhdXRob3JpdHk/LmNhcGFiaWxpdGllc1xuICAgICAgOiB1bmRlZmluZWQpXG4gICAgY29uc3QgcmF3ID0gZnJvbnRlbmQoe1xuICAgICAgY2FwYWJpbGl0aWVzOiBtb2R1bGVDYXBhYmlsaXRpZXMsXG4gICAgICBmaWxlbmFtZTogc291cmNlLmZpbGVuYW1lLFxuICAgICAgbGFuZ3VhZ2U6IHNvdXJjZS5sYW5ndWFnZSxcbiAgICAgIHByb2dyYW06IHtcbiAgICAgICAgY2xhc3NlczogdmlzaWJsZUNsYXNzZXNCeU5hbWUsXG4gICAgICAgIGZ1bmN0aW9uczogdmlzaWJsZUZ1bmN0aW9ucyxcbiAgICAgICAgaXNFbnRyeTogc291cmNlLmlkID09IGlucHV0LmVudHJ5TW9kdWxlLFxuICAgICAgICBlcnJvcnM6IHZpc2libGVFcnJvcnNCeU5hbWUsXG4gICAgICAgIHJlY29yZHM6IHZpc2libGVSZWNvcmRzQnlOYW1lLFxuICAgICAgICB2YWx1ZVJlY29yZHM6IHZpc2libGVWYWx1ZVJlY29yZHNCeU5hbWVcbiAgICAgIH0sXG4gICAgICBzb3VyY2U6IHNvdXJjZS5zb3VyY2VcbiAgICB9KVxuXG4gICAgaWYgKG1vZHVsZUNhcGFiaWxpdGllcykgcmF3LmNhcGFiaWxpdGllcyA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0Q2FwYWJpbGl0eURlY2xhcmF0aW9uW119ICovIChtb2R1bGVDYXBhYmlsaXRpZXMpXG4gICAgaWYgKChyYXcuY2xhc3Nlcz8ubGVuZ3RoID8/IDApID4gMCAmJiAhc291cmNlLmZhY2FkZT8ucHVibGljRGVjbGFyYXRpb25zLnNvbWUoKHtraW5kfSkgPT4ga2luZCA9PSBcImNsYXNzXCIpKSB7XG4gICAgICBzZW1hbnRpY0ZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIlVOU1VQUE9SVEVEX1NZTlRBWFwiLFxuICAgICAgICBcIlRhc2sgMDMzIHJlZmVyZW5jZSBjbGFzc2VzIGFyZSBub3Qgc3VwcG9ydGVkIGJ5IHRoZSBUYXNrIDAxMCBzZW1hbnRpYyBwcm9ncmFtIHByb2ZpbGUuXCIsXG4gICAgICAgIHJhdy5jbGFzc2VzPy5bMF0/LmxvY2F0aW9uID8/IHJhdy5sb2NhdGlvbilcbiAgICB9XG5cbiAgICBpZiAoc291cmNlLmlkID09IGlucHV0LmVudHJ5TW9kdWxlICYmIHJhdy5lbnRyeVBvaW50LmJvZHkuc3RhdGVtZW50cy5sZW5ndGggPT0gMCkge1xuICAgICAgc2VtYW50aWNGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJJTlZBTElEX0VOVFJZX01PRFVMRVwiLCBgU2VsZWN0ZWQgZW50cnkgbW9kdWxlICcke3NvdXJjZS5pZH0nIGhhcyBubyBleGVjdXRhYmxlIHN0YXRlbWVudHMuYCwgcmF3LmVudHJ5UG9pbnQubG9jYXRpb24pXG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB2YWxpZGF0ZVBhcnNlZE1vZHVsZShyYXcsIHNvdXJjZS5sYW5ndWFnZSwge1xuICAgICAgICBjYWxsRWZmZWN0czogdmlzaWJsZUNhbGxFZmZlY3RzLFxuICAgICAgICBlcnJvcnM6IHZpc2libGVFcnJvcnNCeUlkLFxuICAgICAgICBmdW5jdGlvbnM6IHZpc2libGVGdW5jdGlvbnMsXG4gICAgICAgIHJlY29yZHM6IHZpc2libGVSZWNvcmRzQnlJZCxcbiAgICAgICAgY2xhc3NlczogdmlzaWJsZUNsYXNzZXNCeUlkXG4gICAgICB9KVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zdCB0YXNrMDM3ID0gc291cmNlLmxhbmd1YWdlID09IFwicnVieVwiICYmIGhlYWRlci5pbXBvcnRzLnNvbWUoKHtmYWNhZGV9KSA9PiBmYWNhZGU/LmlkZW50aXR5LnN0YXJ0c1dpdGgoXCJzZW1hbnRpZm9sZC50YXNrMDM3LlwiKSlcblxuICAgICAgaWYgKHRhc2swMzcgJiYgZXJyb3IgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZERpYWdub3N0aWMgJiYgZXJyb3IuY29kZSA9PSBcIlVOS05PV05fTUVUSE9EXCIgJiZcbiAgICAgICAgZXJyb3IuZGV0YWlsLnN0YXJ0c1dpdGgoXCJDbGFzcyAnVENQU29ja2V0J1wiKSkge1xuICAgICAgICBmYWNhZGVGYWlsdXJlKFwicnVieVwiLCBcIlNURExJQl9GQUNBREVfTUVNQkVSX1VOU1VQUE9SVEVEXCIsIGVycm9yLmRldGFpbCwgZXJyb3IubG9jYXRpb24pXG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cbiAgICByZWtleURlY2xhcmF0aW9ucyhyYXcsIHNvdXJjZS5pZClcbiAgICBjb25zdCBsb2NhbENhbGxFZmZlY3RzID0gbW9kdWxlVW5jaGVja2VkRXJyb3JFZmZlY3RzKHJhdywge2NhbGxFZmZlY3RzOiB2aXNpYmxlQ2FsbEVmZmVjdHMsIGZ1bmN0aW9uczogdmlzaWJsZUZ1bmN0aW9uc30pXG5cbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIHJhdy5mdW5jdGlvbnMpIHtcbiAgICAgIGNhbGxFZmZlY3RzQnlEZWNsYXJhdGlvbklkLnNldCgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgbmV3IFNldChsb2NhbENhbGxFZmZlY3RzLmdldChkZWNsYXJhdGlvbi5uYW1lKSA/PyBbXSkpXG4gICAgfVxuICAgIGFubm90YXRlUGFyc2VkTW9kdWxlKHJhdywgc291cmNlKVxuICAgIHJlYmFzZVBhcnNlZE1vZHVsZVByb3ZlbmFuY2UocmF3LCByZWdpc3RlcmVkU291cmNlcywgc291cmNlSWQpXG5cbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIHtkZWNsYXJhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24sIHN5bWJvbEtpbmQ6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRGVjbGFyYXRpb25LaW5kfT59ICovXG4gICAgY29uc3QgZGVjbGFyYXRpb25zQnlOYW1lID0gbmV3IE1hcCgpXG5cbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIHJhdy5yZWNvcmRzID8/IFtdKSBkZWNsYXJhdGlvbnNCeU5hbWUuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIHtkZWNsYXJhdGlvbiwgc3ltYm9sS2luZDogXCJyZWNvcmRcIn0pXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiByYXcuY2xhc3NlcyA/PyBbXSkgZGVjbGFyYXRpb25zQnlOYW1lLnNldChkZWNsYXJhdGlvbi5uYW1lLCB7ZGVjbGFyYXRpb24sIHN5bWJvbEtpbmQ6IFwiY2xhc3NcIn0pXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiByYXcuZXJyb3JzID8/IFtdKSBkZWNsYXJhdGlvbnNCeU5hbWUuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIHtkZWNsYXJhdGlvbiwgc3ltYm9sS2luZDogXCJlcnJvclwifSlcbiAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIHJhdy5mdW5jdGlvbnMpIGRlY2xhcmF0aW9uc0J5TmFtZS5zZXQoZGVjbGFyYXRpb24ubmFtZSwge2RlY2xhcmF0aW9uLCBzeW1ib2xLaW5kOiBcImZ1bmN0aW9uXCJ9KVxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNFeHBvcnRbXX0gKi9cbiAgICBjb25zdCBleHBvcnRzID0gaGVhZGVyLmV4cG9ydHMubWFwKChyZXF1ZXN0KSA9PiB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IGRlY2xhcmF0aW9uc0J5TmFtZS5nZXQocmVxdWVzdC5sb2NhbE5hbWUpXG5cbiAgICAgIGlmICghcmVzb2x2ZWQpIHNlbWFudGljRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiVU5SRVNPTFZFRF9FWFBPUlRcIiwgYFVua25vd24gZXhwb3J0ZWQgZGVjbGFyYXRpb24gJyR7cmVxdWVzdC5sb2NhbE5hbWV9Jy5gLCByZXF1ZXN0LmxvY2F0aW9uKVxuICAgICAgaWYgKHJlcXVlc3QudHlwZU9ubHkgJiYgcmVzb2x2ZWQuc3ltYm9sS2luZCAhPSBcInJlY29yZFwiKSB7XG4gICAgICAgIHNlbWFudGljRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiRVhQT1JUX0tJTkRfTUlTTUFUQ0hcIiwgYFR5cGUgZXhwb3J0ICcke3JlcXVlc3QuZXhwb3J0ZWROYW1lfScgZG9lcyBub3QgbmFtZSBhIHJlY29yZC5gLCByZXF1ZXN0LmxvY2F0aW9uKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBkZWNsYXJhdGlvbklkOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKHJlc29sdmVkLmRlY2xhcmF0aW9uLmlkKSxcbiAgICAgICAgZXhwb3J0ZWROYW1lOiByZXF1ZXN0LmV4cG9ydGVkTmFtZSxcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXhwb3J0XCIpLFxuICAgICAgICBsb2NhdGlvbjogcmVxdWVzdC5sb2NhdGlvbixcbiAgICAgICAgc291cmNlUHJvdmVuYW5jZTogc291cmNlQXNzb2NpYXRpb24ocmVxdWVzdC5sb2NhdGlvbiwge1xuICAgICAgICAgIGRlY2xhcmF0aW9uOiByZXF1ZXN0LmRlY2xhcmF0aW9uTG9jYXRpb24gPz8gcmVxdWVzdC5sb2NhdGlvbixcbiAgICAgICAgICBleHBvcnRlZE5hbWU6IHJlcXVlc3QuZXhwb3J0ZWROYW1lTG9jYXRpb24gPz8gcmVxdWVzdC5sb2NhdGlvbixcbiAgICAgICAgICBsb2NhbE5hbWU6IHJlcXVlc3QubG9jYWxOYW1lTG9jYXRpb24gPz8gcmVxdWVzdC5sb2NhdGlvblxuICAgICAgICB9LCBzb3VyY2VJZCksXG4gICAgICAgIHN5bWJvbEtpbmQ6IHJlc29sdmVkLnN5bWJvbEtpbmRcbiAgICAgIH1cbiAgICB9KVxuICAgIGNvbnN0IGV4cG9ydGVkTmFtZXMgPSBuZXcgU2V0KClcblxuICAgIGZvciAoY29uc3QgZXhwb3J0ZWQgb2YgZXhwb3J0cykge1xuICAgICAgaWYgKGV4cG9ydGVkTmFtZXMuaGFzKGV4cG9ydGVkLmV4cG9ydGVkTmFtZSkpIHtcbiAgICAgICAgc2VtYW50aWNGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJEVVBMSUNBVEVfRVhQT1JUXCIsIGBEdXBsaWNhdGUgZXhwb3J0ICcke2V4cG9ydGVkLmV4cG9ydGVkTmFtZX0nLmAsIGV4cG9ydGVkLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgZXhwb3J0ZWROYW1lcy5hZGQoZXhwb3J0ZWQuZXhwb3J0ZWROYW1lKVxuICAgIH1cblxuICAgIGNvbnN0IHtlbnRyeVBvaW50LCAuLi5tb2R1bGVXaXRob3V0RW50cnl9ID0gcmF3XG4gICAgY29uc3QgbW9kdWxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9ICovICh7XG4gICAgICAuLi5tb2R1bGVXaXRob3V0RW50cnksXG4gICAgICAuLi4oc291cmNlLmlkID09IGlucHV0LmVudHJ5TW9kdWxlID8ge2VudHJ5UG9pbnR9IDoge30pLFxuICAgICAgZXhwb3J0cyxcbiAgICAgIGlkOiBzb3VyY2UuaWQsXG4gICAgICBpbXBvcnRzLFxuICAgICAgLi4uKHNvdXJjZS5mYWNhZGUgPyB7c3RkbGliRmFjYWRlOiB7aWRlbnRpdHk6IHNvdXJjZS5mYWNhZGUuaWRlbnRpdHksIHZlcnNpb246IHNvdXJjZS5mYWNhZGUudmVyc2lvbn19IDoge30pLFxuICAgICAgc291cmNlRmlsZW5hbWU6IHNvdXJjZS5maWxlbmFtZVxuICAgIH0pXG5cbiAgICBpZiAoc291cmNlLmZhY2FkZSkgdmFsaWRhdGVQYXJzZWRGYWNhZGUoc291cmNlLmZhY2FkZSwgbW9kdWxlKVxuXG4gICAgcGFyc2VkLnNldChzb3VyY2UuaWQsIG1vZHVsZSlcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZW50cnlNb2R1bGU6IGlucHV0LmVudHJ5TW9kdWxlLFxuICAgIGtpbmQ6IFwiUHJvZ3JhbVwiLFxuICAgIG1vZHVsZXM6IG9yZGVyZWRJZHMubWFwKChpZCkgPT4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1Byb2dyYW1Nb2R1bGV9ICovIChwYXJzZWQuZ2V0KGlkKSkpLFxuICAgIC4uLihyZXF1ZXN0ZWRBdXRob3JpdHkgPyB7XG4gICAgICBzdGRsaWJDb250cmFjdDoge1xuICAgICAgICBpZGVudGl0eTogcmVxdWVzdGVkQXV0aG9yaXR5LmlkLFxuICAgICAgICAuLi4ocmVxdWVzdGVkQXV0aG9yaXR5LmNvbnRyYWN0VmVyc2lvbiAhPT0gdW5kZWZpbmVkID8ge2NvbnRyYWN0VmVyc2lvbjogcmVxdWVzdGVkQXV0aG9yaXR5LmNvbnRyYWN0VmVyc2lvbn0gOiB7fSlcbiAgICAgIH1cbiAgICB9IDogZmFjYWRlQXV0aG9yaXR5ICYmIFwiY29udHJhY3RzXCIgaW4gZmFjYWRlQXV0aG9yaXR5ID8ge3N0ZGxpYkNvbnRyYWN0czogZmFjYWRlQXV0aG9yaXR5LmNvbnRyYWN0c31cbiAgICAgIDogZmFjYWRlQXV0aG9yaXR5ID8ge3N0ZGxpYkNvbnRyYWN0OiBmYWNhZGVBdXRob3JpdHkuY29udHJhY3R9IDoge30pLFxuICAgIC4uLihmYWNhZGVSZWNvcmRzLmxlbmd0aCA+IDAgPyB7c3RkbGliRmFjYWRlczogc3RkbGliRmFjYWRlUHJvZ3JhbURlc2NyaXB0b3IoYXBwbGljYXRpb25Tb3VyY2VzWzBdLmxhbmd1YWdlLCBmYWNhZGVSZWNvcmRzKX0gOiB7fSksXG4gICAgc291cmNlczogcmVnaXN0ZXJlZFNvdXJjZXNcbiAgfVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHBhcnNlci1vd25lZCBuYXRpdmUgbW9kdWxlIGFuZCBzeW1ib2wgZXZpZGVuY2UgdG8gZmFjYWRlIHJvb3RzLlxuICogTXV0YXRpbmcgdGhlIHByaXZhdGUgaGVhZGVyIHJlcXVlc3RzIGtlZXBzIHRoZSBwcm9vZiBhdHRhY2hlZCB0byB0aGUgZXhhY3QgaW1wb3J0IG5vZGUuXG4gKiBAcGFyYW0ge1Byb2dyYW1Tb3VyY2VbXX0gc291cmNlcyAtIENhbGxlci1vd25lZCBzb3VyY2VzLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBQcm9ncmFtSGVhZGVyPn0gaGVhZGVycyAtIFBhcnNlci1vd25lZCBzb3VyY2UgaGVhZGVycy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zdGRsaWItZmFjYWRlcy5qc1wiKS5TdGRsaWJGYWNhZGVSZWNvcmRbXX0gU2VsZWN0ZWQgZmFjYWRlIHJvb3RzLlxuICovXG5mdW5jdGlvbiByZXNvbHZlRmFjYWRlSW1wb3J0cyhzb3VyY2VzLCBoZWFkZXJzKSB7XG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc3RkbGliLWZhY2FkZXMuanNcIikuU3RkbGliRmFjYWRlUmVjb3JkW119ICovXG4gIGNvbnN0IHJvb3RzID0gW11cblxuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgY29uc3QgaGVhZGVyID0gcmVxdWlyZWRNYXBWYWx1ZShoZWFkZXJzLCBzb3VyY2UuaWQpXG5cbiAgICBpZiAoc291cmNlLmxhbmd1YWdlID09IFwicnVieVwiKSByZXNvbHZlUnVieVRhc2swMzdGYWNhZGVzKHNvdXJjZSwgaGVhZGVyLCByb290cylcblxuICAgIGlmIChzb3VyY2UubGFuZ3VhZ2UgPT0gXCJwaHBcIikge1xuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIGhlYWRlci5iaW5kaW5ncyA/PyBbXSkge1xuICAgICAgICBjb25zdCBwYXJ0cyA9IGJpbmRpbmcubmF0aXZlTmFtZS5zcGxpdChcIlxcXFxcIilcbiAgICAgICAgY29uc3Qgc3ltYm9sID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChwYXJ0cy5wb3AoKSlcbiAgICAgICAgY29uc3QgbmF0aXZlTW9kdWxlID0gcGFydHMuam9pbihcIlxcXFxcIilcblxuICAgICAgICBpZiAoIW5hdGl2ZU1vZHVsZS5zdGFydHNXaXRoKFwiU2VtYW50aWZvbGRcXFxcVGFzazAzNlxcXFxcIikpIGNvbnRpbnVlXG4gICAgICAgIGNvbnN0IGZhY2FkZSA9IHJlc29sdmVGYWNhZGVBdChzb3VyY2UsIG5hdGl2ZU1vZHVsZSwgc3ltYm9sLCBiaW5kaW5nLmxvY2F0aW9uKVxuXG4gICAgICAgIGhlYWRlci5pbXBvcnRzLnB1c2goe1xuICAgICAgICAgIGRlY2xhcmF0aW9uTG9jYXRpb246IGJpbmRpbmcubG9jYXRpb24sXG4gICAgICAgICAgZmFjYWRlLFxuICAgICAgICAgIGltcG9ydGVkTmFtZTogXCIqXCIsXG4gICAgICAgICAgaW1wb3J0ZWROYW1lTG9jYXRpb246IGJpbmRpbmcubG9jYXRpb24sXG4gICAgICAgICAgbG9jYWxOYW1lOiBcIlwiLFxuICAgICAgICAgIGxvY2FsTmFtZUxvY2F0aW9uOiBiaW5kaW5nLmxvY2F0aW9uLFxuICAgICAgICAgIGxvY2F0aW9uOiBiaW5kaW5nLmxvY2F0aW9uLFxuICAgICAgICAgIG5hbWVzcGFjZTogdHJ1ZSxcbiAgICAgICAgICBwYXRoTG9jYXRpb246IGJpbmRpbmcubG9jYXRpb24sXG4gICAgICAgICAgc3BlY2lmaWVyOiBuYXRpdmVNb2R1bGUsXG4gICAgICAgICAgc3RkbGliQ2FuZGlkYXRlOiB0cnVlLFxuICAgICAgICAgIHR5cGVPbmx5OiBmYWxzZVxuICAgICAgICB9KVxuICAgICAgICByb290cy5wdXNoKGZhY2FkZSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHJlcXVlc3Qgb2YgaGVhZGVyLmltcG9ydHMpIHtcbiAgICAgIGNvbnN0IGphdmFDYW5kaWRhdGUgPSBzb3VyY2UubGFuZ3VhZ2UgPT0gXCJqYXZhXCIgJiYgcmVxdWVzdC5zcGVjaWZpZXIuc3RhcnRzV2l0aChcInNlbWFudGlmb2xkLnRhc2swMzYuXCIpXG5cbiAgICAgIGlmICghcmVxdWVzdC5zdGRsaWJDYW5kaWRhdGUgJiYgIWphdmFDYW5kaWRhdGUpIGNvbnRpbnVlXG4gICAgICBpZiAocmVxdWVzdC5mYWNhZGUpIGNvbnRpbnVlXG4gICAgICBpZiAoL1xcLig/OmJ1bmRsZXxkbGx8bm9kZXxzbykkL2l1LnRlc3QocmVxdWVzdC5zcGVjaWZpZXIpKSB7XG4gICAgICAgIGZhY2FkZUZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIlNURExJQl9GQUNBREVfTkFUSVZFX0VYVEVOU0lPTl9VTlNVUFBPUlRFRFwiLFxuICAgICAgICAgIFwiTmF0aXZlLWV4dGVuc2lvbiBsb2FkaW5nIGNhbm5vdCBwYXJ0aWNpcGF0ZSBpbiBhIHBvcnRhYmxlIHN0ZGxpYiBmYWNhZGUuXCIsIHJlcXVlc3QucGF0aExvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3Qgc3VwcGxpZWQgPSBbLi4uaGVhZGVycy5lbnRyaWVzKCldLmZpbmQoKFssIGNhbmRpZGF0ZV0pID0+IGNhbmRpZGF0ZS5uYXRpdmVOYW1lID09IHJlcXVlc3Quc3BlY2lmaWVyKVxuXG4gICAgICBpZiAoc3VwcGxpZWQpIHtcbiAgICAgICAgZmFjYWRlRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiU1RETElCX0ZBQ0FERV9TSEFET1dFRFwiLFxuICAgICAgICAgIGBDYWxsZXItc3VwcGxpZWQgbW9kdWxlICcke3N1cHBsaWVkWzBdfScgcmVwbGFjZXMgdGhlIGNhdGFsb2d1ZWQgbmF0aXZlIGZhY2FkZSBpZGVudGl0eSAnJHtyZXF1ZXN0LnNwZWNpZmllcn0nLmAsIHJlcXVlc3QucGF0aExvY2F0aW9uKVxuICAgICAgfVxuICAgICAgY29uc3QgZmFjYWRlID0gcmVxdWVzdC5uYW1lc3BhY2VcbiAgICAgICAgPyByZXNvbHZlRmFjYWRlTW9kdWxlQXQoc291cmNlLCByZXF1ZXN0LnNwZWNpZmllciwgcmVxdWVzdC5wYXRoTG9jYXRpb24pXG4gICAgICAgIDogcmVzb2x2ZUZhY2FkZUF0KHNvdXJjZSwgcmVxdWVzdC5zcGVjaWZpZXIsIHJlcXVlc3QuaW1wb3J0ZWROYW1lLCByZXF1ZXN0LmltcG9ydGVkTmFtZUxvY2F0aW9uID8/IHJlcXVlc3QubG9jYXRpb24pXG5cbiAgICAgIHJlcXVlc3QuZmFjYWRlID0gZmFjYWRlXG4gICAgICByb290cy5wdXNoKGZhY2FkZSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcm9vdHNcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBleGFjdCBUYXNrIDAzNyBSdWJ5IHJlZmVyZW5jZXMgdW5kZXIgYSBsaXRlcmFsIHNvY2tldCBhY3RpdmF0aW9uIGVkZ2UuXG4gKiBAcGFyYW0ge1Byb2dyYW1Tb3VyY2V9IHNvdXJjZSAtIEltcG9ydGluZyBSdWJ5IHNvdXJjZS5cbiAqIEBwYXJhbSB7UHJvZ3JhbUhlYWRlcn0gaGVhZGVyIC0gUGFyc2VyLW93bmVkIFJ1YnkgaGVhZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdGRsaWItZmFjYWRlcy5qc1wiKS5TdGRsaWJGYWNhZGVSZWNvcmRbXX0gcm9vdHMgLSBTZWxlY3RlZCBmYWNhZGUgcm9vdHMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVJ1YnlUYXNrMDM3RmFjYWRlcyhzb3VyY2UsIGhlYWRlciwgcm9vdHMpIHtcbiAgY29uc3QgYWN0aXZhdGlvbkluZGV4ID0gaGVhZGVyLmltcG9ydHMuZmluZEluZGV4KCh7c3BlY2lmaWVyLCBzdGRsaWJDYW5kaWRhdGV9KSA9PiBzdGRsaWJDYW5kaWRhdGUgJiYgc3BlY2lmaWVyID09IFwic29ja2V0XCIpXG5cbiAgaWYgKGFjdGl2YXRpb25JbmRleCA8IDApIHJldHVyblxuICBjb25zdCBhY3RpdmF0aW9uID0gLyoqIEB0eXBlIHtQcm9ncmFtSW1wb3J0UmVxdWVzdH0gKi8gKGhlYWRlci5pbXBvcnRzLnNwbGljZShhY3RpdmF0aW9uSW5kZXgsIDEpWzBdKVxuICBjb25zdCBiaW5kaW5ncyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgcmVmZXJlbmNlIG9mIGhlYWRlci5uYXRpdmVSZWZlcmVuY2VzID8/IFtdKSB7XG4gICAgaWYgKHJlZmVyZW5jZS5uYXRpdmVNb2R1bGUgIT0gXCJzb2NrZXRcIiAmJiByZWZlcmVuY2UubmF0aXZlTW9kdWxlICE9IFwicnVieTpLZXJuZWxcIikgY29udGludWVcbiAgICBjb25zdCBsb2NhbE5hbWUgPSByZWZlcmVuY2UuZm9ybSA9PSBcInJlY2VpdmVyLWNhbGxcIiA/IFwiS2VybmVsLnB1dHNcIiA6IHJlZmVyZW5jZS5zeW1ib2xcblxuICAgIGlmIChiaW5kaW5ncy5oYXMobG9jYWxOYW1lKSkgY29udGludWVcbiAgICBiaW5kaW5ncy5hZGQobG9jYWxOYW1lKVxuICAgIGNvbnN0IGZhY2FkZSA9IHJlc29sdmVGYWNhZGVBdChzb3VyY2UsIHJlZmVyZW5jZS5uYXRpdmVNb2R1bGUsIHJlZmVyZW5jZS5zeW1ib2wsIHJlZmVyZW5jZS5sb2NhdGlvbilcblxuICAgIGhlYWRlci5pbXBvcnRzLnB1c2goe1xuICAgICAgZGVjbGFyYXRpb25Mb2NhdGlvbjogcmVmZXJlbmNlLmxvY2F0aW9uLFxuICAgICAgZmFjYWRlLFxuICAgICAgaW1wb3J0ZWROYW1lOiByZWZlcmVuY2Uuc3ltYm9sLFxuICAgICAgaW1wb3J0ZWROYW1lTG9jYXRpb246IHJlZmVyZW5jZS5sb2NhdGlvbixcbiAgICAgIGxvY2FsTmFtZSxcbiAgICAgIGxvY2FsTmFtZUxvY2F0aW9uOiByZWZlcmVuY2UubG9jYXRpb24sXG4gICAgICBsb2NhdGlvbjogcmVmZXJlbmNlLmxvY2F0aW9uLFxuICAgICAgcGF0aExvY2F0aW9uOiBhY3RpdmF0aW9uLnBhdGhMb2NhdGlvbixcbiAgICAgIHNwZWNpZmllcjogcmVmZXJlbmNlLm5hdGl2ZU1vZHVsZSxcbiAgICAgIHN0ZGxpYkNhbmRpZGF0ZTogdHJ1ZSxcbiAgICAgIHR5cGVPbmx5OiBmYWxzZVxuICAgIH0pXG4gICAgcm9vdHMucHVzaChmYWNhZGUpXG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBvbmUgZXhhY3QgbmF0aXZlIG1vZHVsZSBhbmQgc3ltYm9sIHdoaWxlIHByZXNlcnZpbmcgcGFyc2VyIGxvY2F0aW9uLlxuICogQHBhcmFtIHtQcm9ncmFtU291cmNlfSBzb3VyY2UgLSBJbXBvcnRpbmcgc291cmNlLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hdGl2ZU1vZHVsZSAtIFBhcnNlci1wcm92ZWQgbmF0aXZlIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzeW1ib2wgLSBQYXJzZXItcHJvdmVkIG5hdGl2ZSBzeW1ib2wuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIElkZW50aXR5IGV2aWRlbmNlIGxvY2F0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3N0ZGxpYi1mYWNhZGVzLmpzXCIpLlN0ZGxpYkZhY2FkZVJlY29yZH0gTG9jYXRlZCBleGFjdCBuYXRpdmUgZmFjYWRlIHJlc29sdXRpb24uXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVGYWNhZGVBdChzb3VyY2UsIG5hdGl2ZU1vZHVsZSwgc3ltYm9sLCBsb2NhdGlvbikge1xuICB0cnkge1xuICAgIHJldHVybiBzdGRsaWJGYWNhZGVSZWdpc3RyeS5yZXNvbHZlRmFjYWRlKHNvdXJjZS5sYW5ndWFnZSwgbmF0aXZlTW9kdWxlLCBzeW1ib2wpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2YgU2VtYW50aWZvbGREaWFnbm9zdGljKSBmYWNhZGVGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgZXJyb3IuY29kZSwgZXJyb3IuZGV0YWlsLCBsb2NhdGlvbilcbiAgICB0aHJvdyBlcnJvclxuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25lIGV4YWN0IG5hbWVzcGFjZS1zdHlsZSBuYXRpdmUgbW9kdWxlIHdoaWxlIHByZXNlcnZpbmcgcGFyc2VyIGxvY2F0aW9uLlxuICogQHBhcmFtIHtQcm9ncmFtU291cmNlfSBzb3VyY2UgLSBJbXBvcnRpbmcgc291cmNlLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hdGl2ZU1vZHVsZSAtIFBhcnNlci1wcm92ZWQgbmF0aXZlIG1vZHVsZSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gSWRlbnRpdHkgZXZpZGVuY2UgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc3RkbGliLWZhY2FkZXMuanNcIikuU3RkbGliRmFjYWRlUmVjb3JkfSBMb2NhdGVkIGV4YWN0IG5hdGl2ZSBmYWNhZGUtbW9kdWxlIHJlc29sdXRpb24uXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVGYWNhZGVNb2R1bGVBdChzb3VyY2UsIG5hdGl2ZU1vZHVsZSwgbG9jYXRpb24pIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gc3RkbGliRmFjYWRlUmVnaXN0cnkucmVzb2x2ZU1vZHVsZShzb3VyY2UubGFuZ3VhZ2UsIG5hdGl2ZU1vZHVsZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBTZW1hbnRpZm9sZERpYWdub3N0aWMpIGZhY2FkZUZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBlcnJvci5jb2RlLCBlcnJvci5kZXRhaWwsIGxvY2F0aW9uKVxuICAgIHRocm93IGVycm9yXG4gIH1cbn1cblxuLyoqXG4gKiBSZWplY3RzIGNhbGxlciBjYXB0dXJlIG9mIGNvbXBpbGVyLW93bmVkIG1vZHVsZS9zb3VyY2UvbmF0aXZlIG5hbWVzIGFuZCBpbXBvcnRlZCBiaW5kaW5ncy5cbiAqIEBwYXJhbSB7UHJvZ3JhbVNvdXJjZVtdfSBhcHBsaWNhdGlvblNvdXJjZXMgLSBDYWxsZXItb3duZWQgc291cmNlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUHJvZ3JhbUhlYWRlcj59IGhlYWRlcnMgLSBDYWxsZXIgcGFyc2VyIGhlYWRlcnMuXG4gKiBAcGFyYW0ge1Byb2dyYW1Tb3VyY2VbXX0gZmFjYWRlU291cmNlcyAtIFNlbGVjdGVkIGNvbXBpbGVyLW93bmVkIGZhY2FkZSBzb3VyY2VzLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRmFjYWRlQ29sbGlzaW9ucyhhcHBsaWNhdGlvblNvdXJjZXMsIGhlYWRlcnMsIGZhY2FkZVNvdXJjZXMpIHtcbiAgY29uc3QgZmFjYWRlSWRzID0gbmV3IFNldChmYWNhZGVTb3VyY2VzLm1hcCgoe2lkfSkgPT4gaWQpKVxuICBjb25zdCBmYWNhZGVGaWxlbmFtZXMgPSBuZXcgU2V0KGZhY2FkZVNvdXJjZXMubWFwKCh7ZmlsZW5hbWV9KSA9PiBmaWxlbmFtZSkpXG4gIGNvbnN0IGZhY2FkZU5hdGl2ZU5hbWVzID0gbmV3IFNldChmYWNhZGVTb3VyY2VzLm1hcCgoc291cmNlKSA9PiBpbnNwZWN0U291cmNlKHNvdXJjZSkubmF0aXZlTmFtZSkuZmlsdGVyKEJvb2xlYW4pKVxuXG4gIGZvciAoY29uc3Qgc291cmNlIG9mIGFwcGxpY2F0aW9uU291cmNlcykge1xuICAgIGNvbnN0IGhlYWRlciA9IHJlcXVpcmVkTWFwVmFsdWUoaGVhZGVycywgc291cmNlLmlkKVxuXG4gICAgaWYgKGZhY2FkZUlkcy5oYXMoc291cmNlLmlkKSB8fCBmYWNhZGVGaWxlbmFtZXMuaGFzKHNvdXJjZS5maWxlbmFtZSkpIHtcbiAgICAgIGZhY2FkZUZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIlNURExJQl9GQUNBREVfTkFNRV9DT0xMSVNJT05cIixcbiAgICAgICAgYENhbGxlciBtb2R1bGUgJyR7c291cmNlLmlkfScgY29sbGlkZXMgd2l0aCBhIGNvbXBpbGVyLW93bmVkIGZhY2FkZSBtb2R1bGUgb3Igc291cmNlIHBhdGguYCwgbW9kdWxlTG9jYXRpb24oc291cmNlLmZpbGVuYW1lLCBzb3VyY2Uuc291cmNlKSlcbiAgICB9XG4gICAgaWYgKGhlYWRlci5uYXRpdmVOYW1lICYmIGZhY2FkZU5hdGl2ZU5hbWVzLmhhcyhoZWFkZXIubmF0aXZlTmFtZSkpIHtcbiAgICAgIGZhY2FkZUZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIlNURExJQl9GQUNBREVfUkVPUEVORURcIixcbiAgICAgICAgYENhbGxlciBzb3VyY2UgcmVvcGVucyB0aGUgY29tcGlsZXItb3duZWQgZmFjYWRlIG5hdGl2ZSBpZGVudGl0eSAnJHtoZWFkZXIubmF0aXZlTmFtZX0nLmAsIG1vZHVsZUxvY2F0aW9uKHNvdXJjZS5maWxlbmFtZSwgc291cmNlLnNvdXJjZSkpXG4gICAgfVxuICAgIGNvbnN0IGltcG9ydGVkQmluZGluZ3MgPSBuZXcgU2V0KGhlYWRlci5pbXBvcnRzLmZpbHRlcigoe2ZhY2FkZX0pID0+IGZhY2FkZSAmJiAhZmFjYWRlLnB1YmxpY0RlY2xhcmF0aW9ucy5zb21lKCh7bmFtZX0pID0+IG5hbWUgPT0gXCJcIikpXG4gICAgICAuZmxhdE1hcCgocmVxdWVzdCkgPT4gcmVxdWVzdC5uYW1lc3BhY2UgJiYgc291cmNlLmxhbmd1YWdlID09IFwicGhwXCJcbiAgICAgICAgPyAoaGVhZGVyLmJpbmRpbmdzID8/IFtdKS5maWx0ZXIoKHtuYXRpdmVOYW1lfSkgPT4gbmF0aXZlTmFtZS5zdGFydHNXaXRoKGAke3JlcXVlc3Quc3BlY2lmaWVyfVxcXFxgKSkubWFwKCh7bG9jYWxOYW1lfSkgPT4gbG9jYWxOYW1lKVxuICAgICAgICA6IHJlcXVlc3QubmFtZXNwYWNlID8gW10gOiBbcmVxdWVzdC5sb2NhbE5hbWVdKSlcbiAgICBjb25zdCBzaGFkb3dlZCA9IGhlYWRlci5leHBvcnRzLmZpbmQoKHtsb2NhbE5hbWV9KSA9PiBpbXBvcnRlZEJpbmRpbmdzLmhhcyhsb2NhbE5hbWUpKVxuXG4gICAgaWYgKHNoYWRvd2VkKSBmYWNhZGVGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJTVERMSUJfRkFDQURFX1NIQURPV0VEXCIsXG4gICAgICBgTG9jYWwgZGVjbGFyYXRpb24gJyR7c2hhZG93ZWQubG9jYWxOYW1lfScgc2hhZG93cyBhIHBhcnNlci1wcm92ZWQgc3RkbGliIGZhY2FkZSBiaW5kaW5nLmAsIHNoYWRvd2VkLmxvY2F0aW9uKVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIGEgcGFyc2VkIGNvbXBpbGVyLW93bmVkIGZhY2FkZSBhZ2FpbnN0IGl0cyByZWdpc3RyeSBkZWNsYXJhdGlvbiBhbmQgY2Fub25pY2FsLW9ubHkgcmVxdWlyZW1lbnRzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zdGRsaWItZmFjYWRlcy5qc1wiKS5TdGRsaWJGYWNhZGVSZWNvcmR9IGZhY2FkZSAtIFNlbGVjdGVkIGZhY2FkZSByZWNvcmQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gbW9kdWxlIC0gUGFyc2VkIHNlbWFudGljIG1vZHVsZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVBhcnNlZEZhY2FkZShmYWNhZGUsIG1vZHVsZSkge1xuICBjb25zdCBleHBvcnRlZCA9IG5ldyBNYXAobW9kdWxlLmV4cG9ydHMubWFwKChpdGVtKSA9PiBbaXRlbS5leHBvcnRlZE5hbWUsIGl0ZW1dKSlcblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGZhY2FkZS5wdWJsaWNEZWNsYXJhdGlvbnMpIHtcbiAgICBpZiAoZGVjbGFyYXRpb24ua2luZCA9PSBcImNsYXNzXCIpIHtcbiAgICAgIHZhbGlkYXRlUGFyc2VkRmFjYWRlQ2xhc3MoZmFjYWRlLCBtb2R1bGUsIGRlY2xhcmF0aW9uLCBleHBvcnRlZC5nZXQoZGVjbGFyYXRpb24ubmFtZSkpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBjb25zdCBleHBvcnRlZERlY2xhcmF0aW9uID0gZXhwb3J0ZWQuZ2V0KGRlY2xhcmF0aW9uLm5hbWUpXG4gICAgY29uc3QgcGFyc2VkID0gZXhwb3J0ZWREZWNsYXJhdGlvbiA/IG1vZHVsZS5mdW5jdGlvbnMuZmluZCgoe2lkfSkgPT4gaWQgPT0gZXhwb3J0ZWREZWNsYXJhdGlvbi5kZWNsYXJhdGlvbklkKSA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IHNpZ25hdHVyZU1hdGNoZXMgPSBwYXJzZWQgJiYgcGFyc2VkLnBhcmFtZXRlcnMubGVuZ3RoID09IGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMubGVuZ3RoICYmXG4gICAgICBwYXJzZWQucGFyYW1ldGVycy5ldmVyeSgocGFyYW1ldGVyLCBpbmRleCkgPT4gcGFyYW1ldGVyLm5hbWUgPT0gZGVjbGFyYXRpb24ucGFyYW1ldGVyc1tpbmRleF0ubmFtZSAmJlxuICAgICAgICBzZW1hbnRpY1R5cGVOYW1lKHBhcmFtZXRlci50eXBlKSA9PSBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzW2luZGV4XS50eXBlKSAmJlxuICAgICAgc2VtYW50aWNUeXBlTmFtZShwYXJzZWQucmV0dXJuVHlwZSkgPT0gZGVjbGFyYXRpb24ucmV0dXJuVHlwZVxuXG4gICAgaWYgKCFzaWduYXR1cmVNYXRjaGVzKSBmYWNhZGVGYWlsdXJlKGZhY2FkZS5sYW5ndWFnZSwgXCJTVERMSUJfRkFDQURFX0RFQ0xBUkFUSU9OX01JU01BVENIXCIsXG4gICAgICBgRmFjYWRlICcke2ZhY2FkZS5pZGVudGl0eX0nIGV4ZWN1dGFibGUgc291cmNlIGRvZXMgbm90IG1hdGNoIHB1YmxpYyBkZWNsYXJhdGlvbiAnJHtkZWNsYXJhdGlvbi5uYW1lfScuYCwgcGFyc2VkPy5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gIH1cbiAgY29uc3QgZGVwZW5kZW5jeUlkcyA9IG5ldyBTZXQoZmFjYWRlLmRlcGVuZGVuY2llcy5tYXAoKGRlcGVuZGVuY3kpID0+XG4gICAgc3RkbGliRmFjYWRlUmVnaXN0cnkucmVzb2x2ZUlkZW50aXR5KGRlcGVuZGVuY3kuaWRlbnRpdHksIGZhY2FkZS5sYW5ndWFnZSwgZGVwZW5kZW5jeS5yYW5nZSkuc291cmNlLmlkKSlcblxuICBpZiAobW9kdWxlLmltcG9ydHMuc29tZSgoe21vZHVsZUlkfSkgPT4gIWRlcGVuZGVuY3lJZHMuaGFzKG1vZHVsZUlkKSkgfHxcbiAgICBbLi4uZGVwZW5kZW5jeUlkc10uc29tZSgobW9kdWxlSWQpID0+ICFtb2R1bGUuaW1wb3J0cy5zb21lKChpbXBvcnRlZCkgPT4gaW1wb3J0ZWQubW9kdWxlSWQgPT0gbW9kdWxlSWQpKSkge1xuICAgIGZhY2FkZUZhaWx1cmUoZmFjYWRlLmxhbmd1YWdlLCBcIlNURExJQl9GQUNBREVfREVDTEFSQVRJT05fTUlTTUFUQ0hcIixcbiAgICAgIGBGYWNhZGUgJyR7ZmFjYWRlLmlkZW50aXR5fScgZXhlY3V0YWJsZSBpbXBvcnRzIGRvIG5vdCBtYXRjaCBpdHMgZGVjbGFyZWQgZGVwZW5kZW5jaWVzLmAsIG1vZHVsZS5sb2NhdGlvbilcbiAgfVxuICBjb25zdCBhbGxvd2VkT3BlcmF0aW9ucyA9IG5ldyBTZXQoZmFjYWRlLnJlcXVpcmVtZW50cy5mbGF0TWFwKCh7b3BlcmF0aW9uc30pID0+IG9wZXJhdGlvbnMpKVxuICBjb25zdCBvcGVyYXRpb25OYW1lcyA9IG5ldyBNYXAoKG1vZHVsZS5jYXBhYmlsaXRpZXMgPz8gW10pLmZsYXRNYXAoKHtvcGVyYXRpb25zfSkgPT4gb3BlcmF0aW9ucy5tYXAoKHtpZCwgbmFtZX0pID0+IFtpZCwgbmFtZV0pKSlcbiAgY29uc3QgdXNlZE9wZXJhdGlvbnMgPSBjb2xsZWN0RWZmZWN0T3BlcmF0aW9ucyhtb2R1bGUsIG9wZXJhdGlvbk5hbWVzKVxuXG4gIGlmIChbLi4udXNlZE9wZXJhdGlvbnNdLnNvbWUoKG9wZXJhdGlvbikgPT4gIWFsbG93ZWRPcGVyYXRpb25zLmhhcyhvcGVyYXRpb24pKSB8fFxuICAgIFsuLi5hbGxvd2VkT3BlcmF0aW9uc10uc29tZSgob3BlcmF0aW9uKSA9PiAhdXNlZE9wZXJhdGlvbnMuaGFzKG9wZXJhdGlvbikpKSB7XG4gICAgZmFjYWRlRmFpbHVyZShmYWNhZGUubGFuZ3VhZ2UsIFwiU1RETElCX0ZBQ0FERV9BVVRIT1JJVFlfRk9SR0VEXCIsXG4gICAgICBgRmFjYWRlICcke2ZhY2FkZS5pZGVudGl0eX0nIGNhbm9uaWNhbCBjYWxscyBkbyBub3QgbWF0Y2ggaXRzIGRlY2xhcmVkIHJlcXVpcmVtZW50cy5gLCBtb2R1bGUubG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBWZXJpZmllcyBvbmUgZXhlY3V0YWJsZSBjb21waWxlci1vd25lZCBmYWNhZGUgY2xhc3MgYWdhaW5zdCBpdHMgY2xvc2VkIGRlc2NyaXB0b3IuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3N0ZGxpYi1mYWNhZGVzLmpzXCIpLlN0ZGxpYkZhY2FkZVJlY29yZH0gZmFjYWRlIC0gT3duaW5nIGZhY2FkZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfSBtb2R1bGUgLSBQYXJzZWQgZmFjYWRlIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc3RkbGliLWZhY2FkZXMuanNcIikuU3RkbGliRmFjYWRlQ2xhc3NEZWNsYXJhdGlvbn0gZGVzY3JpcHRvciAtIFJlZ2lzdHJ5IGRlc2NyaXB0b3IuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRXhwb3J0IHwgdW5kZWZpbmVkfSBleHBvcnRlZCAtIE1hdGNoaW5nIGV4cG9ydCBldmlkZW5jZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVBhcnNlZEZhY2FkZUNsYXNzKGZhY2FkZSwgbW9kdWxlLCBkZXNjcmlwdG9yLCBleHBvcnRlZCkge1xuICBjb25zdCBwYXJzZWQgPSBleHBvcnRlZD8uc3ltYm9sS2luZCA9PSBcImNsYXNzXCJcbiAgICA/IG1vZHVsZS5jbGFzc2VzPy5maW5kKCh7aWR9KSA9PiBpZCA9PSBleHBvcnRlZC5kZWNsYXJhdGlvbklkKSA6IHVuZGVmaW5lZFxuICBjb25zdCBmYWlsdXJlTmFtZXMgPSBuZXcgTWFwKChtb2R1bGUuY2FwYWJpbGl0aWVzID8/IFtdKS5mbGF0TWFwKCh7ZmFpbHVyZXN9KSA9PiBmYWlsdXJlcy5tYXAoKHtpZCwgbmFtZX0pID0+IFtpZCwgbmFtZV0pKSlcbiAgY29uc3QgY29uc3RydWN0b3JGYWlsdXJlcyA9IHBhcnNlZD8uY29uc3RydWN0b3IuZmFpbHVyZUlkcz8ubWFwKChpZCkgPT4gZmFpbHVyZU5hbWVzLmdldChpZCkpID8/IFtdXG4gIGNvbnN0IGNvbnN0cnVjdG9yTWF0Y2hlcyA9IHBhcnNlZD8ubmFtZSA9PSBkZXNjcmlwdG9yLm5hbWUgJiYgcGFyc2VkLm93bmVyc2hpcD8ua2luZCA9PSBcIm93bmVkUmVzb3VyY2VcIiAmJlxuICAgIHBhcnNlZC5jb25zdHJ1Y3Rvci5lZmZlY3RzPy5qb2luKFwiLFwiKSA9PSBkZXNjcmlwdG9yLmNvbnN0cnVjdG9yLmVmZmVjdHMuam9pbihcIixcIikgJiZcbiAgICBjb25zdHJ1Y3RvckZhaWx1cmVzLmpvaW4oXCIsXCIpID09IGRlc2NyaXB0b3IuY29uc3RydWN0b3IuZmFpbHVyZXMuam9pbihcIixcIikgJiZcbiAgICBwYXJzZWQuY29uc3RydWN0b3IucGFyYW1ldGVycy5sZW5ndGggPT0gZGVzY3JpcHRvci5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuICAgIHBhcnNlZC5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLmV2ZXJ5KChwYXJhbWV0ZXIsIGluZGV4KSA9PiBwYXJhbWV0ZXIubmFtZSA9PSBkZXNjcmlwdG9yLmNvbnN0cnVjdG9yLnBhcmFtZXRlcnNbaW5kZXhdLm5hbWUgJiZcbiAgICAgIHNlbWFudGljVHlwZU5hbWUocGFyYW1ldGVyLnR5cGUpID09IGRlc2NyaXB0b3IuY29uc3RydWN0b3IucGFyYW1ldGVyc1tpbmRleF0udHlwZSlcbiAgY29uc3QgbWV0aG9kc01hdGNoID0gcGFyc2VkPy5tZXRob2RzLmxlbmd0aCA9PSBkZXNjcmlwdG9yLm1ldGhvZHMubGVuZ3RoICYmIGRlc2NyaXB0b3IubWV0aG9kcy5ldmVyeSgoZXhwZWN0ZWQsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgbWV0aG9kID0gcGFyc2VkPy5tZXRob2RzW2luZGV4XVxuICAgIGNvbnN0IGFjdHVhbEZhaWx1cmVzID0gbWV0aG9kPy5mYWlsdXJlSWRzPy5tYXAoKGlkKSA9PiBmYWlsdXJlTmFtZXMuZ2V0KGlkKSkgPz8gW11cbiAgICBjb25zdCBvcGVyYXRpb24gPSBtZXRob2Q/LmJvZHkuc3RhdGVtZW50cy5mbGF0TWFwKChzdGF0ZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBzdGF0ZW1lbnQua2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiXG4gICAgICAgID8gc3RhdGVtZW50LmV4cHJlc3Npb24gOiBzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiA/IHN0YXRlbWVudC5pbml0aWFsaXplciA6IHVuZGVmaW5lZFxuXG4gICAgICByZXR1cm4gZXhwcmVzc2lvbj8ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIgPyBbZXhwcmVzc2lvbl0gOiBbXVxuICAgIH0pWzBdXG4gICAgY29uc3QgZmxvdyA9IG9wZXJhdGlvbj8ucmVzb2x1dGlvbi5yZXNvdXJjZUZsb3dcbiAgICBjb25zdCB0ZXJtaW5hbEZhaWx1cmVJZCA9IGZsb3c/LmtpbmQgPT0gXCJib3Jyb3dcIiB8fCBmbG93Py5raW5kID09IFwiY2xvc2VcIiA/IGZsb3cudGVybWluYWxGYWlsdXJlSWQgOiB1bmRlZmluZWRcblxuICAgIGlmICh0ZXJtaW5hbEZhaWx1cmVJZCkgYWN0dWFsRmFpbHVyZXMucHVzaChmYWlsdXJlTmFtZXMuZ2V0KHRlcm1pbmFsRmFpbHVyZUlkKSlcbiAgICByZXR1cm4gbWV0aG9kPy5uYW1lID09IGV4cGVjdGVkLm5hbWUgJiYgbWV0aG9kLmVmZmVjdHM/LmpvaW4oXCIsXCIpID09IGV4cGVjdGVkLmVmZmVjdHMuam9pbihcIixcIikgJiZcbiAgICAgIGFjdHVhbEZhaWx1cmVzLmpvaW4oXCIsXCIpID09IGV4cGVjdGVkLmZhaWx1cmVzLmpvaW4oXCIsXCIpICYmIG1ldGhvZC5wYXJhbWV0ZXJzLmxlbmd0aCA9PSBleHBlY3RlZC5wYXJhbWV0ZXJzLmxlbmd0aCAmJlxuICAgICAgbWV0aG9kLnBhcmFtZXRlcnMuZXZlcnkoKHBhcmFtZXRlciwgcGFyYW1ldGVySW5kZXgpID0+XG4gICAgICAgIHBhcmFtZXRlci5uYW1lID09IGV4cGVjdGVkLnBhcmFtZXRlcnNbcGFyYW1ldGVySW5kZXhdLm5hbWUgJiZcbiAgICAgICAgc2VtYW50aWNUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSkgPT0gZXhwZWN0ZWQucGFyYW1ldGVyc1twYXJhbWV0ZXJJbmRleF0udHlwZSkgJiZcbiAgICAgIHNlbWFudGljVHlwZU5hbWUobWV0aG9kLnJldHVyblR5cGUpID09IGV4cGVjdGVkLnJldHVyblR5cGVcbiAgfSlcblxuICBpZiAoIWNvbnN0cnVjdG9yTWF0Y2hlcyB8fCAhbWV0aG9kc01hdGNoKSB7XG4gICAgZmFjYWRlRmFpbHVyZShmYWNhZGUubGFuZ3VhZ2UsIFwiU1RETElCX0ZBQ0FERV9ERUNMQVJBVElPTl9NSVNNQVRDSFwiLFxuICAgICAgYEZhY2FkZSAnJHtmYWNhZGUuaWRlbnRpdHl9JyBleGVjdXRhYmxlIHNvdXJjZSBkb2VzIG5vdCBtYXRjaCBwdWJsaWMgY2xhc3MgJyR7ZGVzY3JpcHRvci5uYW1lfScuYCwgcGFyc2VkPy5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBDb2xsZWN0cyBjYW5vbmljYWwgb3BlcmF0aW9uIG5hbWVzIHJlYWNoZWQgaW4gb25lIGZhY2FkZSBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljUHJvZ3JhbU1vZHVsZX0gbW9kdWxlIC0gUGFyc2VkIGZhY2FkZSBtb2R1bGUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIHN0cmluZz59IG9wZXJhdGlvbk5hbWVzIC0gQ2Fub25pY2FsIG5hbWVzIGJ5IG9wZXJhdGlvbiBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtTZXQ8c3RyaW5nPn0gVXNlZCBvcGVyYXRpb24gbmFtZXMuXG4gKi9cbmZ1bmN0aW9uIGNvbGxlY3RFZmZlY3RPcGVyYXRpb25zKG1vZHVsZSwgb3BlcmF0aW9uTmFtZXMpIHtcbiAgY29uc3QgdXNlZCA9IG5ldyBTZXQoKVxuICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKVxuXG4gIC8qKlxuICAgKiBWaXNpdHMgb25lIHNlbWFudGljIHN1YnRyZWUgd2l0aG91dCBmb2xsb3dpbmcgYXV0aG9yaXR5IG9yIHByb3ZlbmFuY2UgZ3JhcGhzLlxuICAgKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gU2VtYW50aWMgc3VidHJlZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdCh2YWx1ZSkge1xuICAgIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXModmFsdWUpKSByZXR1cm5cbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodmFsdWUpICYmIFJlZmxlY3QuZ2V0KHZhbHVlLCBcImtpbmRcIikgPT0gXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBuYW1lID0gb3BlcmF0aW9uTmFtZXMuZ2V0KFJlZmxlY3QuZ2V0KHZhbHVlLCBcIm9wZXJhdGlvblwiKSlcblxuICAgICAgaWYgKG5hbWUpIHVzZWQuYWRkKG5hbWUpXG4gICAgfVxuICAgIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKHZhbHVlKSkge1xuICAgICAgaWYgKGtleSAhPSBcImNhcGFiaWxpdGllc1wiICYmIGtleSAhPSBcImxvY2F0aW9uXCIgJiYga2V5ICE9IFwicHJvdmVuYW5jZVwiICYmIGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikgdmlzaXQoY2hpbGQpXG4gICAgfVxuICB9XG4gIHZpc2l0KG1vZHVsZSlcbiAgcmV0dXJuIHVzZWRcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgcGFyc2VkIHNlbWFudGljIHR5cGUgdG8gdGhlIGZhY2FkZSBkZWNsYXJhdGlvbiB2b2NhYnVsYXJ5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gdHlwZSAtIFBhcnNlZCB0eXBlLlxuICogQHJldHVybnMge3N0cmluZ30gQ2xvc2VkIGNhbm9uaWNhbCBwdWJsaWMgdHlwZSBuYW1lLlxuICovXG5mdW5jdGlvbiBzZW1hbnRpY1R5cGVOYW1lKHR5cGUpIHtcbiAgaWYgKHR5cGUua2luZCA9PSBcIlR5cGVSZWZlcmVuY2VcIikgcmV0dXJuIHR5cGUubmFtZVxuICByZXR1cm4gdHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIgJiYgdHlwZS52YWx1ZVR5cGUua2luZCA9PSBcIlR5cGVSZWZlcmVuY2VcIlxuICAgID8gYG9wdGlvbmFsOiR7dHlwZS52YWx1ZVR5cGUubmFtZX1gIDogXCJ1bnN1cHBvcnRlZFwiXG59XG5cbi8qKlxuICogVGhyb3dzIG9uZSBzdGFibGUgbG9jYXRlZCBmYWNhZGUgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb2RlIC0gU3RhYmxlIGRpYWdub3N0aWMgY29kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtZXNzYWdlIC0gRGlhZ25vc3RpYyBkZXRhaWwuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSBsb2NhdGlvbiAtIFBhcnNlci1vd25lZCBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHtuZXZlcn0gQWx3YXlzIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gZmFjYWRlRmFpbHVyZShsYW5ndWFnZSwgY29kZSwgbWVzc2FnZSwgbG9jYXRpb24pIHtcbiAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7Y29kZSwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBtZXNzYWdlfSlcbn1cblxuLyoqXG4gKiBSZWplY3RzIHNvdXJjZS1wcm9maWxlIGlkZW50aXRpZXMgd2hvc2UgbG9va3VwIG9yIHJlb3BlbmluZyB3b3VsZCBkZXBlbmQgb24gY2FsbGVyIG9yZGVyLlxuICogQHBhcmFtIHtQcm9ncmFtU291cmNlW119IHNvdXJjZXMgLSBDb21wbGV0ZSB2YWxpZGF0ZWQgc291cmNlIHNldC5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUHJvZ3JhbUhlYWRlcj59IGhlYWRlcnMgLSBQYXJzZXItb3duZWQgbW9kdWxlIGhlYWRlcnMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVOYXRpdmVNb2R1bGVJZGVudGl0aWVzKHNvdXJjZXMsIGhlYWRlcnMpIHtcbiAgaWYgKCFzb3VyY2VzLmV2ZXJ5KCh7bGFuZ3VhZ2V9KSA9PiBsYW5ndWFnZSA9PSBcImphdmFcIikgJiYgIXNvdXJjZXMuZXZlcnkoKHtsYW5ndWFnZX0pID0+IGxhbmd1YWdlID09IFwicnVieVwiKSkgcmV0dXJuXG4gIGNvbnN0IG9yZGVyZWQgPSBbLi4uc291cmNlc10uc29ydCgobGVmdCwgcmlnaHQpID0+IGxlZnQuZmlsZW5hbWUubG9jYWxlQ29tcGFyZShyaWdodC5maWxlbmFtZSwgXCJlbi1VU1wiKSB8fFxuICAgIGxlZnQuaWQubG9jYWxlQ29tcGFyZShyaWdodC5pZCwgXCJlbi1VU1wiKSlcbiAgY29uc3Qgb3duZXJzID0gbmV3IE1hcCgpXG5cbiAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygb3JkZXJlZCkge1xuICAgIGNvbnN0IG5hdGl2ZU5hbWUgPSByZXF1aXJlZE1hcFZhbHVlKGhlYWRlcnMsIHNvdXJjZS5pZCkubmF0aXZlTmFtZVxuXG4gICAgaWYgKCFuYXRpdmVOYW1lKSBjb250aW51ZVxuICAgIGNvbnN0IGVhcmxpZXIgPSBvd25lcnMuZ2V0KG5hdGl2ZU5hbWUpXG5cbiAgICBpZiAoZWFybGllcikge1xuICAgICAgY29uc3QgbGFiZWwgPSBzb3VyY2UubGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBcIkphdmFcIiA6IFwiUnVieVwiXG5cbiAgICAgIHNlbWFudGljRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiRFVQTElDQVRFX01PRFVMRVwiLFxuICAgICAgICBgRHVwbGljYXRlICR7bGFiZWx9IG5hdGl2ZSBtb2R1bGUgaWRlbnRpdHkgJyR7bmF0aXZlTmFtZX0nIGluICcke2VhcmxpZXIuZmlsZW5hbWV9JyBhbmQgJyR7c291cmNlLmZpbGVuYW1lfScuYCxcbiAgICAgICAgbW9kdWxlTG9jYXRpb24oc291cmNlLmZpbGVuYW1lLCBzb3VyY2Uuc291cmNlKSlcbiAgICB9XG4gICAgb3duZXJzLnNldChuYXRpdmVOYW1lLCBzb3VyY2UpXG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgYW5kIHNuYXBzaG90cyBvbmUgY2FsbGVyLXN1cHBsaWVkIHByb2dyYW0gc291cmNlIGRlc2NyaXB0b3IuXG4gKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIENhbmRpZGF0ZSBzb3VyY2UgZGVzY3JpcHRvci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIFNvdXJjZSBpbmRleC5cbiAqIEByZXR1cm5zIHtQcm9ncmFtU291cmNlfSBWYWxpZGF0ZWQgc291cmNlIGRlc2NyaXB0b3IuXG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlU291cmNlKGNhbmRpZGF0ZSwgaW5kZXgpIHtcbiAgaWYgKCFpc1BsYWluT2JqZWN0KGNhbmRpZGF0ZSkpIHtcbiAgICByZXR1cm4gaW52YWxpZFByb2dyYW0oYFByb2dyYW0gc291cmNlICR7aW5kZXh9IHJlcXVpcmVzIGEgc3RhYmxlIG1vZHVsZSBJRCwgc2FmZSBmaWxlbmFtZSwgbGFuZ3VhZ2UsIGFuZCBzb3VyY2UgdGV4dC5gKVxuICB9XG4gIGlmICghaXNQbGFpbk9iamVjdChjYW5kaWRhdGUpIHx8IHR5cGVvZiBjYW5kaWRhdGUuaWQgIT0gXCJzdHJpbmdcIiB8fCAhbW9kdWxlSWRQYXR0ZXJuLnRlc3QoY2FuZGlkYXRlLmlkKSB8fFxuICAgIHR5cGVvZiBjYW5kaWRhdGUuZmlsZW5hbWUgIT0gXCJzdHJpbmdcIiB8fCAhaXNTYWZlU291cmNlUGF0aChjYW5kaWRhdGUuZmlsZW5hbWUpIHx8XG4gICAgdHlwZW9mIGNhbmRpZGF0ZS5zb3VyY2UgIT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgY2FuZGlkYXRlLmxhbmd1YWdlICE9IFwic3RyaW5nXCIpIHtcbiAgICBpbnZhbGlkUHJvZ3JhbShgUHJvZ3JhbSBzb3VyY2UgJHtpbmRleH0gcmVxdWlyZXMgYSBzdGFibGUgbW9kdWxlIElELCBzYWZlIGZpbGVuYW1lLCBsYW5ndWFnZSwgYW5kIHNvdXJjZSB0ZXh0LmApXG4gIH1cbiAgbGFuZ3VhZ2VSZWdpc3RyeS5yZWNvcmQoY2FuZGlkYXRlLmxhbmd1YWdlKVxuICBpZiAoIXByb2dyYW1MYW5ndWFnZXMuaGFzKGNhbmRpZGF0ZS5sYW5ndWFnZSkpIHVuc3VwcG9ydGVkUm9sZShjYW5kaWRhdGUubGFuZ3VhZ2UsIFwibXVsdGktZmlsZSBmcm9udGVuZFwiKVxuXG4gIHJldHVybiAvKiogQHR5cGUge1Byb2dyYW1Tb3VyY2V9ICovICh7XG4gICAgZmlsZW5hbWU6IGNhbmRpZGF0ZS5maWxlbmFtZSxcbiAgICBpZDogY2FuZGlkYXRlLmlkLFxuICAgIGxhbmd1YWdlOiBjYW5kaWRhdGUubGFuZ3VhZ2UsXG4gICAgb3duZXJzaGlwOiBcImFwcGxpY2F0aW9uXCIsXG4gICAgc291cmNlOiBjYW5kaWRhdGUuc291cmNlXG4gIH0pXG59XG5cbi8qKlxuICogRGlzcGF0Y2hlcyBwYXJzZXItb3duZWQgbW9kdWxlIGhlYWRlciBpbnNwZWN0aW9uIGZvciBvbmUgY29ob3J0IHNvdXJjZS5cbiAqIEBwYXJhbSB7e2ZpbGVuYW1lOiBzdHJpbmcsIGxhbmd1YWdlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlLCBzb3VyY2U6IHN0cmluZ319IHNvdXJjZSAtIFZhbGlkYXRlZCBzb3VyY2UuXG4gKiBAcmV0dXJucyB7UHJvZ3JhbUhlYWRlcn0gUGFyc2VyLW93bmVkIGltcG9ydC9leHBvcnQgaGVhZGVyLlxuICovXG5mdW5jdGlvbiBpbnNwZWN0U291cmNlKHNvdXJjZSkge1xuICBpZiAoc291cmNlLmxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IHNvdXJjZS5sYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIikge1xuICAgIHJldHVybiBpbnNwZWN0SmF2YVNjcmlwdFR5cGVTY3JpcHRNb2R1bGUoLyoqIEB0eXBlIHt7ZmlsZW5hbWU6IHN0cmluZywgbGFuZ3VhZ2U6IFwiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCIsIHNvdXJjZTogc3RyaW5nfX0gKi8gKHNvdXJjZSkpXG4gIH1cbiAgaWYgKHNvdXJjZS5sYW5ndWFnZSA9PSBcInJ1YnlcIikge1xuICAgIHJldHVybiBpbnNwZWN0UnVieU1vZHVsZSgvKiogQHR5cGUge3tmaWxlbmFtZTogc3RyaW5nLCBsYW5ndWFnZTogXCJydWJ5XCIsIHNvdXJjZTogc3RyaW5nfX0gKi8gKHNvdXJjZSkpXG4gIH1cbiAgaWYgKHNvdXJjZS5sYW5ndWFnZSA9PSBcInBocFwiKSB7XG4gICAgcmV0dXJuIGluc3BlY3RQaHBNb2R1bGUoLyoqIEB0eXBlIHt7ZmlsZW5hbWU6IHN0cmluZywgbGFuZ3VhZ2U6IFwicGhwXCIsIHNvdXJjZTogc3RyaW5nfX0gKi8gKHNvdXJjZSkpXG4gIH1cbiAgaWYgKHNvdXJjZS5sYW5ndWFnZSA9PSBcImphdmFcIikge1xuICAgIHJldHVybiBpbnNwZWN0SmF2YU1vZHVsZSgvKiogQHR5cGUge3tmaWxlbmFtZTogc3RyaW5nLCBsYW5ndWFnZTogXCJqYXZhXCIsIHNvdXJjZTogc3RyaW5nfX0gKi8gKHNvdXJjZSkpXG4gIH1cblxuICByZXR1cm4gdW5zdXBwb3J0ZWRSb2xlKHNvdXJjZS5sYW5ndWFnZSwgXCJtdWx0aS1maWxlIGZyb250ZW5kXCIpXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25seSBhbiBleHBsaWNpdCByZWxhdGl2ZSBFU00gc3BlY2lmaWVyIGFnYWluc3QgY2FsbGVyLXN1cHBsaWVkIGZpbGVuYW1lcy5cbiAqIEBwYXJhbSB7e2ZpbGVuYW1lOiBzdHJpbmcsIGxhbmd1YWdlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfX0gc291cmNlIC0gSW1wb3J0aW5nIHNvdXJjZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzcGVjaWZpZXIgLSBQYXJzZXItb3duZWQgcmVsYXRpdmUgc3BlY2lmaWVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbG9jYXRpb24gLSBTcGVjaWZpZXIgbG9jYXRpb24uXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFByb2dyYW1Tb3VyY2U+fSBzb3VyY2VzIC0gU291cmNlcyBieSBleGFjdCBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUHJvZ3JhbUhlYWRlcj59IGhlYWRlcnMgLSBQYXJzZXItb3duZWQgbW9kdWxlIGhlYWRlcnMuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXNvbHZlZCBtb2R1bGUgaWRlbnRpdHkuXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVJbXBvcnRNb2R1bGUoc291cmNlLCBzcGVjaWZpZXIsIGxvY2F0aW9uLCBzb3VyY2VzLCBoZWFkZXJzKSB7XG4gIGlmIChzb3VyY2UubGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHtcbiAgICBjb25zdCBtYXRjaGVkID0gWy4uLmhlYWRlcnMuZW50cmllcygpXS5maW5kKChbLCBoZWFkZXJdKSA9PiBoZWFkZXIubmF0aXZlTmFtZSA9PSBzcGVjaWZpZXIpXG5cbiAgICBpZiAoIW1hdGNoZWQpIHNlbWFudGljRmFpbHVyZShzb3VyY2UubGFuZ3VhZ2UsIFwiVU5SRVNPTFZFRF9NT0RVTEVcIiwgYEltcG9ydCAnJHtzcGVjaWZpZXJ9JyBkb2VzIG5vdCBpZGVudGlmeSBhIHN1cHBsaWVkIHNvdXJjZS5gLCBsb2NhdGlvbilcblxuICAgIHJldHVybiBtYXRjaGVkWzBdXG4gIH1cbiAgY29uc3QgZGlyZWN0b3J5ID0gc291cmNlLmZpbGVuYW1lLnNwbGl0KFwiL1wiKS5zbGljZSgwLCAtMSlcbiAgY29uc3QgcGFydHMgPSBbLi4uZGlyZWN0b3J5XVxuXG4gIGZvciAoY29uc3QgcGFydCBvZiBzcGVjaWZpZXIuc3BsaXQoXCIvXCIpKSB7XG4gICAgaWYgKHBhcnQgPT0gXCJcIiB8fCBwYXJ0ID09IFwiLlwiKSBjb250aW51ZVxuICAgIGlmIChwYXJ0ID09IFwiLi5cIikge1xuICAgICAgaWYgKHBhcnRzLmxlbmd0aCA9PSAwKSBzZW1hbnRpY0ZhaWx1cmUoc291cmNlLmxhbmd1YWdlLCBcIlVOU0FGRV9NT0RVTEVfUEFUSFwiLCBgSW1wb3J0ICcke3NwZWNpZmllcn0nIGVzY2FwZXMgdGhlIHN1cHBsaWVkIHNvdXJjZSByb290LmAsIGxvY2F0aW9uKVxuICAgICAgcGFydHMucG9wKClcbiAgICB9IGVsc2UgcGFydHMucHVzaChwYXJ0KVxuICB9XG4gIGxldCBleGFjdCA9IHBhcnRzLmpvaW4oXCIvXCIpXG5cbiAgaWYgKHNvdXJjZS5sYW5ndWFnZSA9PSBcInJ1YnlcIiAmJiAhZXhhY3QuZW5kc1dpdGgoXCIucmJcIikpIGV4YWN0ICs9IFwiLnJiXCJcbiAgY29uc3QgY2FuZGlkYXRlcyA9IFtleGFjdF1cblxuICBpZiAoc291cmNlLmxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiICYmIGV4YWN0LmVuZHNXaXRoKFwiLmpzXCIpKSBjYW5kaWRhdGVzLnB1c2goYCR7ZXhhY3Quc2xpY2UoMCwgLTMpfS50c2ApXG4gIGNvbnN0IG1hdGNoZWQgPSBjYW5kaWRhdGVzLmZsYXRNYXAoKGZpbGVuYW1lKSA9PiBzb3VyY2VzLmhhcyhmaWxlbmFtZSkgPyBbc291cmNlcy5nZXQoZmlsZW5hbWUpXSA6IFtdKVswXVxuXG4gIGlmICghbWF0Y2hlZCkgc2VtYW50aWNGYWlsdXJlKHNvdXJjZS5sYW5ndWFnZSwgXCJVTlJFU09MVkVEX01PRFVMRVwiLCBgSW1wb3J0ICcke3NwZWNpZmllcn0nIGRvZXMgbm90IGlkZW50aWZ5IGEgc3VwcGxpZWQgc291cmNlLmAsIGxvY2F0aW9uKVxuXG4gIHJldHVybiBtYXRjaGVkLmlkXG59XG5cbi8qKlxuICogQnVpbGRzIHRoZSBzb3VyY2UtcHJvZmlsZSBzcGVsbGluZyB1c2VkIHRvIHJlc29sdmUgb25lIG5hbWVzcGFjZS1xdWFsaWZpZWQgaW1wb3J0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEltcG9ydGluZyBzb3VyY2UgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gbmF0aXZlTmFtZSAtIERlcGVuZGVuY3kgbmFtZXNwYWNlL21vZHVsZSBuYW1lLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0V4cG9ydH0gZXhwb3J0ZWQgLSBJbXBvcnRlZCBleHBvcnQuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBTb3VyY2UtcHJvZmlsZSBiaW5kaW5nIHNwZWxsaW5nLlxuICovXG5mdW5jdGlvbiBxdWFsaWZpZWRJbXBvcnROYW1lKGxhbmd1YWdlLCBuYXRpdmVOYW1lLCBleHBvcnRlZCkge1xuICBpZiAoIW5hdGl2ZU5hbWUpIHRocm93IG5ldyBFcnJvcihcIk5hbWVzcGFjZSBpbXBvcnQgZGVwZW5kZW5jeSBoYXMgbm8gcGFyc2VyLW93bmVkIG5hdGl2ZSBuYW1lLlwiKVxuICBpZiAobGFuZ3VhZ2UgPT0gXCJydWJ5XCIpIHJldHVybiBgJHtuYXRpdmVOYW1lfSR7ZXhwb3J0ZWQuc3ltYm9sS2luZCA9PSBcImZ1bmN0aW9uXCIgPyBcIi5cIiA6IFwiOjpcIn0ke2V4cG9ydGVkLmV4cG9ydGVkTmFtZX1gXG4gIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIikge1xuICAgIGNvbnN0IGNsYXNzTmFtZSA9IG5hdGl2ZU5hbWUuc3BsaXQoXCIuXCIpLmF0KC0xKVxuXG4gICAgaWYgKCFjbGFzc05hbWUpIHRocm93IG5ldyBFcnJvcihcIkphdmEgaW1wb3J0IGRlcGVuZGVuY3kgaGFzIG5vIGNsYXNzIG5hbWUuXCIpXG5cbiAgICByZXR1cm4gZXhwb3J0ZWQuc3ltYm9sS2luZCA9PSBcImZ1bmN0aW9uXCIgPyBgJHtjbGFzc05hbWV9LiR7ZXhwb3J0ZWQuZXhwb3J0ZWROYW1lfWAgOiBjbGFzc05hbWVcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgbmFtZXNwYWNlIGltcG9ydCBwcm9maWxlICcke2xhbmd1YWdlfScuYClcbn1cblxuLyoqXG4gKiBTb3J0cyB0aGUgZXhwbGljaXQgbW9kdWxlIGdyYXBoIGluIHN0YWJsZSBkZXBlbmRlbmN5LWZpcnN0IG9yZGVyLlxuICogQHBhcmFtIHtQcm9ncmFtU291cmNlW119IHNvdXJjZXMgLSBWYWxpZGF0ZWQgc291cmNlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywge3NvdXJjZTogUHJvZ3JhbVNvdXJjZSwgcmVxdWVzdHM6IHttb2R1bGVJZDogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259W119Pn0gZ3JhcGggLSBSZXNvbHZlZCBncmFwaC5cbiAqIEByZXR1cm5zIHtzdHJpbmdbXX0gRGVwZW5kZW5jeS1maXJzdCBtb2R1bGUgaWRlbnRpdGllcy5cbiAqL1xuZnVuY3Rpb24gdG9wb2xvZ2ljYWxPcmRlcihzb3VyY2VzLCBncmFwaCkge1xuICBjb25zdCBjb21wbGV0ZSA9IG5ldyBTZXQoKVxuICBjb25zdCBhY3RpdmUgPSBuZXcgU2V0KClcbiAgLyoqIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgY29uc3QgcmVzdWx0ID0gW11cblxuICAvKipcbiAgICogVmlzaXRzIG9uZSBtb2R1bGUgYW5kIGl0cyBkZXBlbmRlbmNpZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCAtIE1vZHVsZSBpZGVudGl0eS5cbiAgICovXG4gIGZ1bmN0aW9uIHZpc2l0KGlkKSB7XG4gICAgaWYgKGNvbXBsZXRlLmhhcyhpZCkpIHJldHVyblxuICAgIGlmIChhY3RpdmUuaGFzKGlkKSkge1xuICAgICAgY29uc3QgZWRnZSA9IHJlcXVpcmVkTWFwVmFsdWUoZ3JhcGgsIGlkKS5yZXF1ZXN0c1swXVxuXG4gICAgICBzZW1hbnRpY0ZhaWx1cmUocmVxdWlyZWRNYXBWYWx1ZShncmFwaCwgaWQpLnNvdXJjZS5sYW5ndWFnZSwgXCJJTVBPUlRfQ1lDTEVcIiwgYEltcG9ydCBjeWNsZSBpbmNsdWRlcyBtb2R1bGUgJyR7aWR9Jy5gLCBlZGdlPy5sb2NhdGlvbilcbiAgICB9XG4gICAgYWN0aXZlLmFkZChpZClcbiAgICBmb3IgKGNvbnN0IHJlcXVlc3Qgb2YgcmVxdWlyZWRNYXBWYWx1ZShncmFwaCwgaWQpLnJlcXVlc3RzKSB2aXNpdChyZXF1ZXN0Lm1vZHVsZUlkKVxuICAgIGFjdGl2ZS5kZWxldGUoaWQpXG4gICAgY29tcGxldGUuYWRkKGlkKVxuICAgIHJlc3VsdC5wdXNoKGlkKVxuICB9XG5cbiAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlcykgdmlzaXQoc291cmNlLmlkKVxuXG4gIHJldHVybiByZXN1bHRcbn1cblxuLyoqXG4gKiBMb29rcyB1cCBvbmUgYWxyZWFkeS1yZXNvbHZlZCBleHBvcnRlZCBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNQcm9ncmFtTW9kdWxlfSBtb2R1bGUgLSBFeHBvcnRpbmcgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0V4cG9ydH0gZXhwb3J0ZWQgLSBSZXNvbHZlZCBleHBvcnQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb259IERlY2xhcmF0aW9uLlxuICovXG5mdW5jdGlvbiBkZWNsYXJhdGlvbkZvcihtb2R1bGUsIGV4cG9ydGVkKSB7XG4gIGNvbnN0IGRlY2xhcmF0aW9ucyA9IGV4cG9ydGVkLnN5bWJvbEtpbmQgPT0gXCJmdW5jdGlvblwiID8gbW9kdWxlLmZ1bmN0aW9ucyA6XG4gICAgZXhwb3J0ZWQuc3ltYm9sS2luZCA9PSBcInJlY29yZFwiID8gbW9kdWxlLnJlY29yZHMgPz8gW10gOiBleHBvcnRlZC5zeW1ib2xLaW5kID09IFwiY2xhc3NcIiA/IG1vZHVsZS5jbGFzc2VzID8/IFtdIDogbW9kdWxlLmVycm9ycyA/PyBbXVxuICBjb25zdCBkZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9ucy5maW5kKCh7aWR9KSA9PiBpZCA9PSBleHBvcnRlZC5kZWNsYXJhdGlvbklkKVxuXG4gIGlmICghZGVjbGFyYXRpb24pIHRocm93IG5ldyBFcnJvcihgUmVzb2x2ZWQgZXhwb3J0ICcke2V4cG9ydGVkLmRlY2xhcmF0aW9uSWR9JyBoYXMgbm8gZGVjbGFyYXRpb24uYClcblxuICByZXR1cm4gZGVjbGFyYXRpb25cbn1cblxuLyoqXG4gKiBQcmVmaXhlcyBtb2R1bGUtb3duZWQgZGVjbGFyYXRpb24gaWRlbnRpdGllcyBhbmQgZXhwbGljaXQgcmVzb2x2ZWQgcmVmZXJlbmNlcyB0byB0aGVtLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gVmFsaWRhdGVkIG1vZHVsZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBtb2R1bGVJZCAtIFN0YWJsZSBtb2R1bGUgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmVrZXlEZWNsYXJhdGlvbnMobW9kdWxlLCBtb2R1bGVJZCkge1xuICBjb25zdCByZXBsYWNlbWVudHMgPSBuZXcgTWFwKClcblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5jbGFzc2VzID8/IFtdKSB7XG4gICAgcmVwbGFjZW1lbnRzLnNldChkZWNsYXJhdGlvbi5pZCwgYCR7bW9kdWxlSWR9IyR7ZGVjbGFyYXRpb24uaWR9YClcbiAgICByZXBsYWNlbWVudHMuc2V0KGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLmlkLCBgJHttb2R1bGVJZH0jJHtkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5pZH1gKVxuICAgIGZvciAoY29uc3QgZmllbGQgb2YgZGVjbGFyYXRpb24uZmllbGRzKSByZXBsYWNlbWVudHMuc2V0KGZpZWxkLmlkLCBgJHttb2R1bGVJZH0jJHtmaWVsZC5pZH1gKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIHJlcGxhY2VtZW50cy5zZXQobWV0aG9kLmlkLCBgJHttb2R1bGVJZH0jJHttZXRob2QuaWR9YClcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5yZWNvcmRzID8/IFtdKSB7XG4gICAgcmVwbGFjZW1lbnRzLnNldChkZWNsYXJhdGlvbi5pZCwgYCR7bW9kdWxlSWR9IyR7ZGVjbGFyYXRpb24uaWR9YClcbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/PyBbXSkge1xuICAgICAgaWYgKHBhcmFtZXRlci5pZCkgcmVwbGFjZW1lbnRzLnNldChwYXJhbWV0ZXIuaWQsIGAke21vZHVsZUlkfSMke3BhcmFtZXRlci5pZH1gKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGRlY2xhcmF0aW9uLmZpZWxkcykgcmVwbGFjZW1lbnRzLnNldChmaWVsZC5pZCwgYCR7bW9kdWxlSWR9IyR7ZmllbGQuaWR9YClcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5lcnJvcnMgPz8gW10pIHJlcGxhY2VtZW50cy5zZXQoZGVjbGFyYXRpb24uaWQsIGAke21vZHVsZUlkfSMke2RlY2xhcmF0aW9uLmlkfWApXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgIHJlcGxhY2VtZW50cy5zZXQoZGVjbGFyYXRpb24uaWQsIGAke21vZHVsZUlkfSMke2RlY2xhcmF0aW9uLmlkfWApXG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPz8gW10pIHtcbiAgICAgIGlmIChwYXJhbWV0ZXIuaWQpIHJlcGxhY2VtZW50cy5zZXQocGFyYW1ldGVyLmlkLCBgJHttb2R1bGVJZH0jJHtwYXJhbWV0ZXIuaWR9YClcbiAgICB9XG4gIH1cblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5yZWNvcmRzID8/IFtdKSB7XG4gICAgZGVjbGFyYXRpb24uaWQgPSByZXBsYWNlbWVudHMuZ2V0KGRlY2xhcmF0aW9uLmlkKVxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzID8/IFtdKSB7XG4gICAgICBwYXJhbWV0ZXIuaWQgPSAvKiogQHR5cGUge3N0cmluZ30gKi8gKHJlcGxhY2VtZW50cy5nZXQoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChwYXJhbWV0ZXIuaWQpKSlcbiAgICB9XG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiBkZWNsYXJhdGlvbi5maWVsZHMpIGZpZWxkLmlkID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyZXBsYWNlbWVudHMuZ2V0KGZpZWxkLmlkKSlcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5lcnJvcnMgPz8gW10pIGRlY2xhcmF0aW9uLmlkID0gcmVwbGFjZW1lbnRzLmdldChkZWNsYXJhdGlvbi5pZClcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkge1xuICAgIGRlY2xhcmF0aW9uLmlkID0gcmVwbGFjZW1lbnRzLmdldChkZWNsYXJhdGlvbi5pZClcbiAgICBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5pZCA9IHJlcGxhY2VtZW50cy5nZXQoZGVjbGFyYXRpb24uY29uc3RydWN0b3IuaWQpXG4gICAgZm9yIChjb25zdCBmaWVsZCBvZiBkZWNsYXJhdGlvbi5maWVsZHMpIGZpZWxkLmlkID0gcmVwbGFjZW1lbnRzLmdldChmaWVsZC5pZClcbiAgICBmb3IgKGNvbnN0IG1ldGhvZCBvZiBkZWNsYXJhdGlvbi5tZXRob2RzKSBtZXRob2QuaWQgPSByZXBsYWNlbWVudHMuZ2V0KG1ldGhvZC5pZClcbiAgICBpZiAoZGVjbGFyYXRpb24ub3duZXJzaGlwPy5raW5kID09IFwib3duZWRSZXNvdXJjZVwiKSB7XG4gICAgICBkZWNsYXJhdGlvbi5vd25lcnNoaXAuZmllbGRJZCA9IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocmVwbGFjZW1lbnRzLmdldChkZWNsYXJhdGlvbi5vd25lcnNoaXAuZmllbGRJZCkpXG4gICAgfVxuICB9XG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgIGRlY2xhcmF0aW9uLmlkID0gcmVwbGFjZW1lbnRzLmdldChkZWNsYXJhdGlvbi5pZClcbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/PyBbXSkge1xuICAgICAgcGFyYW1ldGVyLmlkID0gLyoqIEB0eXBlIHtzdHJpbmd9ICovIChyZXBsYWNlbWVudHMuZ2V0KC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAocGFyYW1ldGVyLmlkKSkpXG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KClcbiAgLyoqXG4gICAqIFJld3JpdGVzIG9ubHkgdHlwZWQgaWRlbnRpdHktYmVhcmluZyBmaWVsZHMgdGhyb3VnaG91dCBvbmUgc2VtYW50aWMgc3VidHJlZS5cbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFNlbWFudGljIHN1YnRyZWUuXG4gICAqL1xuICBmdW5jdGlvbiB2aXNpdCh2YWx1ZSkge1xuICAgIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXModmFsdWUpKSByZXR1cm5cbiAgICBzZWVuLmFkZCh2YWx1ZSlcbiAgICBjb25zdCBvYmplY3QgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAodmFsdWUpXG5cbiAgICBpZiAoKG9iamVjdC5raW5kID09IFwiUmVjb3JkVHlwZVwiIHx8IG9iamVjdC5raW5kID09IFwiUmVmZXJlbmNlVHlwZVwiIHx8IG9iamVjdC5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIgfHxcbiAgICAgIG9iamVjdC5raW5kID09IFwiRXJyb3JUeXBlXCIgfHwgb2JqZWN0LmtpbmQgPT0gXCJSZXNvbHZlZEZ1bmN0aW9uU2lnbmF0dXJlXCIgfHxcbiAgICAgIG9iamVjdC5raW5kID09IFwiUmVzb2x2ZWRDb25zdHJ1Y3RvclNpZ25hdHVyZVwiIHx8IG9iamVjdC5raW5kID09IFwiUmVzb2x2ZWRNZXRob2RTaWduYXR1cmVcIikgJiZcbiAgICAgIHR5cGVvZiBvYmplY3QuZGVjbGFyYXRpb25JZCA9PSBcInN0cmluZ1wiICYmIHJlcGxhY2VtZW50cy5oYXMob2JqZWN0LmRlY2xhcmF0aW9uSWQpKSB7XG4gICAgICBvYmplY3QuZGVjbGFyYXRpb25JZCA9IHJlcGxhY2VtZW50cy5nZXQob2JqZWN0LmRlY2xhcmF0aW9uSWQpXG4gICAgfVxuICAgIGlmICgob2JqZWN0LmtpbmQgPT0gXCJNZW1iZXJSZWFkXCIgfHwgb2JqZWN0LmtpbmQgPT0gXCJQcml2YXRlRmllbGRSZWFkXCIgfHwgb2JqZWN0LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiKSAmJlxuICAgICAgdHlwZW9mIG9iamVjdC5maWVsZCA9PSBcInN0cmluZ1wiICYmIHJlcGxhY2VtZW50cy5oYXMob2JqZWN0LmZpZWxkKSkge1xuICAgICAgb2JqZWN0LmZpZWxkID0gcmVwbGFjZW1lbnRzLmdldChvYmplY3QuZmllbGQpXG4gICAgfVxuICAgIGlmIChvYmplY3Qua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIgJiYgdHlwZW9mIG9iamVjdC5tZXRob2QgPT0gXCJzdHJpbmdcIiAmJiByZXBsYWNlbWVudHMuaGFzKG9iamVjdC5tZXRob2QpKSB7XG4gICAgICBvYmplY3QubWV0aG9kID0gcmVwbGFjZW1lbnRzLmdldChvYmplY3QubWV0aG9kKVxuICAgIH1cbiAgICBpZiAob2JqZWN0LmtpbmQgPT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIiAmJiB0eXBlb2Ygb2JqZWN0LmNsYXNzSWQgPT0gXCJzdHJpbmdcIiAmJiByZXBsYWNlbWVudHMuaGFzKG9iamVjdC5jbGFzc0lkKSkge1xuICAgICAgb2JqZWN0LmNsYXNzSWQgPSByZXBsYWNlbWVudHMuZ2V0KG9iamVjdC5jbGFzc0lkKVxuICAgIH1cbiAgICBpZiAob2JqZWN0LmtpbmQgPT0gXCJUeXBlVmFyaWFibGVSZWZlcmVuY2VcIiAmJiB0eXBlb2Ygb2JqZWN0LnBhcmFtZXRlcklkID09IFwic3RyaW5nXCIgJiYgcmVwbGFjZW1lbnRzLmhhcyhvYmplY3QucGFyYW1ldGVySWQpKSB7XG4gICAgICBvYmplY3QucGFyYW1ldGVySWQgPSByZXBsYWNlbWVudHMuZ2V0KG9iamVjdC5wYXJhbWV0ZXJJZClcbiAgICB9XG4gICAgZm9yIChjb25zdCBjaGlsZCBvZiBPYmplY3QudmFsdWVzKG9iamVjdCkpIGlmICh0eXBlb2YgY2hpbGQgPT0gXCJvYmplY3RcIikgdmlzaXQoY2hpbGQpXG4gIH1cbiAgdmlzaXQobW9kdWxlKVxufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBzb3VyY2UgYXNzb2NpYXRpb24gZm9yIGEgcGFyc2VyLW93bmVkIG1vZHVsZSBoZWFkZXIgbm9kZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gTm9kZSBvcmlnaW4uXG4gKiBAcGFyYW0ge1JlYWRvbmx5PFJlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uPj59IHJhbmdlcyAtIEV4YWN0IGF2YWlsYWJsZSBoZWFkZXIgcm9sZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlSWQgLSBQcm9ncmFtLXdpZGUgc291cmNlIGlkZW50aXR5LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTm9kZVNvdXJjZVByb3ZlbmFuY2V9IFNvdXJjZSBhc3NvY2lhdGlvbi5cbiAqL1xuZnVuY3Rpb24gc291cmNlQXNzb2NpYXRpb24obG9jYXRpb24sIHJhbmdlcywgc291cmNlSWQpIHtcbiAgcmV0dXJuIHtcbiAgICBvcmlnaW46IHtraW5kOiBcInNvdXJjZVwiLCBsb2NhdGlvbiwgc291cmNlSWR9LFxuICAgIHJhbmdlcyxcbiAgICBzY2hlbWE6IFwiU2VtYW50aWZvbGROb2RlUHJvdmVuYW5jZVwiLFxuICAgIHZlcnNpb246IDFcbiAgfVxufVxuXG4vKipcbiAqIFJlYmluZHMgb25lIHBhcnNlci1sb2NhbCBwcm92ZW5hbmNlIHJlZ2lzdHJ5IHRvIHRoZSBjb21wbGV0ZSBwcm9ncmFtIHNvdXJjZSByZWdpc3RyeS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIE5ld2x5IHBhcnNlZCBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlZ2lzdGVyZWRTb3VyY2VbXX0gc291cmNlcyAtIFByb2dyYW0td2lkZSByZWdpc3RyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2VJZCAtIE93bmluZyBzb3VyY2UgaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmViYXNlUGFyc2VkTW9kdWxlUHJvdmVuYW5jZShtb2R1bGUsIHNvdXJjZXMsIHNvdXJjZUlkKSB7XG4gIGlmICghbW9kdWxlLnByb3ZlbmFuY2UpIHRocm93IG5ldyBFcnJvcihcIlBhcnNlZCBwcm9ncmFtIG1vZHVsZSBoYXMgbm8gc291cmNlIHByb3ZlbmFuY2UuXCIpXG4gIGNvbnN0IHNlZW4gPSBuZXcgV2Vha1NldCgpXG5cbiAgLyoqXG4gICAqIFJlYmluZHMgc291cmNlLW9yaWdpbiBpZGVudGl0aWVzIHRocm91Z2hvdXQgb25lIHNlbWFudGljIHN1YnRyZWUuXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBTZW1hbnRpYyBzdWJ0cmVlLlxuICAgKi9cbiAgZnVuY3Rpb24gdmlzaXQodmFsdWUpIHtcbiAgICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKHZhbHVlKSkgcmV0dXJuXG4gICAgc2Vlbi5hZGQodmFsdWUpXG4gICAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKHZhbHVlKVxuICAgIGNvbnN0IHByb3ZlbmFuY2UgPSBjYW5kaWRhdGUuc291cmNlUHJvdmVuYW5jZVxuICAgIGNvbnN0IG9yaWdpbiA9IGlzUGxhaW5PYmplY3QocHJvdmVuYW5jZSkgPyBwcm92ZW5hbmNlLm9yaWdpbiA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKGlzUGxhaW5PYmplY3Qob3JpZ2luKSAmJiBvcmlnaW4ua2luZCA9PSBcInNvdXJjZVwiKSBvcmlnaW4uc291cmNlSWQgPSBzb3VyY2VJZFxuICAgIGZvciAoY29uc3QgY2hpbGQgb2YgT2JqZWN0LnZhbHVlcyhjYW5kaWRhdGUpKSB2aXNpdChjaGlsZClcbiAgfVxuICB2aXNpdChtb2R1bGUpXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBtb2R1bGUucHJvdmVuYW5jZS5ub2Rlcykge1xuICAgIGlmIChub2RlLm9yaWdpbi5raW5kID09IFwic291cmNlXCIpIG5vZGUub3JpZ2luLnNvdXJjZUlkID0gc291cmNlSWRcbiAgfVxuICBtb2R1bGUucHJvdmVuYW5jZS5zb3VyY2VzID0gc291cmNlc1xufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciBhIGNhbmRpZGF0ZSBpcyBhIGRpcmVjdCBwbGFpbiBvYmplY3QuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIG9iamVjdC5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIEJvb2xlYW4odmFsdWUpICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSAmJiBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpID09IE9iamVjdC5wcm90b3R5cGVcbn1cblxuLyoqXG4gKiBSZWFkcyBhIHZhbHVlIHdob3NlIG1hcCBrZXkgd2FzIHZhbGlkYXRlZCBlYXJsaWVyIGluIHByb2dyYW0gYXNzZW1ibHkuXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBUPn0gbWFwIC0gTWFwIHdpdGggYSBwcmV2aW91c2x5IHZhbGlkYXRlZCBrZXkuXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gUmVxdWlyZWQga2V5LlxuICogQHJldHVybnMge1R9IFN0b3JlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gcmVxdWlyZWRNYXBWYWx1ZShtYXAsIGtleSkge1xuICBjb25zdCB2YWx1ZSA9IG1hcC5nZXQoa2V5KVxuXG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdGVkIG1hcCB2YWx1ZSAnJHtrZXl9Jy5gKVxuXG4gIHJldHVybiB2YWx1ZVxufVxuXG4vKipcbiAqIFJhaXNlcyBhIHN0YWJsZSBtYWxmb3JtZWQgcHJvZ3JhbSByZXF1ZXN0IGRpYWdub3N0aWMuXG4gKiBAcGFyYW0ge3N0cmluZ30gbWVzc2FnZSAtIFN0YWJsZSByZXF1ZXN0IGZhaWx1cmUgZGV0YWlsLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBpbnZhbGlkUHJvZ3JhbShtZXNzYWdlKSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiSU5WQUxJRF9QUk9HUkFNXCIsIGxhbmd1YWdlOiBcInByb2dyYW1cIiwgbWVzc2FnZX0pXG59XG4iXX0=
|