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
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { unsupportedCapability } from "../diagnostic.js";
|
|
3
|
+
import { isDenseArray } from "../array.js";
|
|
3
4
|
import { validateBackendTypes } from "../semantic/validate.js";
|
|
4
|
-
import { validateTargetBindingIdentifier, validateTargetIdentifier } from "./identifiers.js";
|
|
5
|
-
import { emitStringLiteral } from "./scalars.js";
|
|
5
|
+
import { validateTargetBindingIdentifier, validateTargetIdentifier, validateTargetTypeIdentifier } from "./identifiers.js";
|
|
6
|
+
import { emitScalarType, emitStringLiteral } from "./scalars.js";
|
|
6
7
|
/** @type {Readonly<Record<import("../semantic/types.js").SemanticUnaryOperation, string>>} */
|
|
7
8
|
const unaryOperationSyntax = Object.freeze({ BooleanNot: "!", IntegerNegate: "-" });
|
|
8
9
|
/** @type {Readonly<Record<import("../semantic/types.js").SemanticBinaryOperation, Readonly<{default: string, php?: string, python?: string, strict?: string}>>>} */
|
|
@@ -24,13 +25,37 @@ const binaryOperationSyntax = Object.freeze({
|
|
|
24
25
|
StringEqual: Object.freeze({ default: "==", strict: "===" }),
|
|
25
26
|
StringNotEqual: Object.freeze({ default: "!=", strict: "!==" })
|
|
26
27
|
});
|
|
28
|
+
const task005Languages = new Set(["php", "ruby", "javascript", "typescript", "java", "dart"]);
|
|
29
|
+
const task006Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
30
|
+
const task007Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
31
|
+
const task008Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
32
|
+
const task009Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
33
|
+
const task011Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
34
|
+
const task012Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
35
|
+
const task014Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
36
|
+
const task032Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
37
|
+
const task033Languages = new Set(["php", "ruby", "javascript", "typescript", "java"]);
|
|
38
|
+
const javaReferenceMethodHooks = new Set(["clone", "equals", "finalize", "getClass", "hashCode", "notify", "notifyAll", "toString", "wait"]);
|
|
39
|
+
const javascriptReferenceMethodHooks = new Set([
|
|
40
|
+
"__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", "__proto__", "constructor",
|
|
41
|
+
"hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"
|
|
42
|
+
]);
|
|
43
|
+
const rubyReferenceMethodHooks = new Set([
|
|
44
|
+
"__send__", "extend", "fetch", "instance_eval", "instance_exec", "method", "method_missing", "public_send",
|
|
45
|
+
"respond_to_missing?", "send", "singleton_class", "size"
|
|
46
|
+
]);
|
|
47
|
+
const javaObjectInstanceMethodSignatures = new Set([
|
|
48
|
+
"clone()", "equals(Object)", "finalize()", "getClass()", "hashCode()", "notify()", "notifyAll()", "toString()",
|
|
49
|
+
"wait()", "wait(long)", "wait(long,int)"
|
|
50
|
+
]);
|
|
27
51
|
/**
|
|
28
52
|
* Checks the intentionally narrow backend contract.
|
|
29
53
|
* @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
|
|
30
|
-
* @param {import("../semantic/types.js").
|
|
54
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
55
|
+
* @param {{externalDeclarationIds?: Set<string>, program?: boolean, visibleFunctions?: Map<string, import("../semantic/types.js").FunctionDeclaration>, visibleRecords?: Map<string, import("../semantic/types.js").RecordDeclaration>, visibleClasses?: Map<string, import("../semantic/types.js").ClassDeclaration>, visibleErrors?: Map<string, import("../semantic/types.js").ErrorDeclaration>, visibleCallEffects?: Map<string, Set<string>>}} [options] - Resolved program validation context.
|
|
31
56
|
* @returns {void}
|
|
32
57
|
*/
|
|
33
|
-
export function validateBackendModule(module, language) {
|
|
58
|
+
export function validateBackendModule(module, language, options = {}) {
|
|
34
59
|
if (!module || typeof module != "object" || Array.isArray(module)) {
|
|
35
60
|
return unsupportedCapability(language, "missing or invalid module", undefined);
|
|
36
61
|
}
|
|
@@ -39,19 +64,87 @@ export function validateBackendModule(module, language) {
|
|
|
39
64
|
if (!Array.isArray(module.functions) || !module.entryPoint || typeof module.entryPoint != "object" ||
|
|
40
65
|
module.entryPoint.kind != "EntryPoint")
|
|
41
66
|
unsupportedCapability(language, "missing or invalid module members", module.location);
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
67
|
+
const declaredRecords = module.records;
|
|
68
|
+
const records = declaredRecords === undefined ? [] : declaredRecords;
|
|
69
|
+
const declaredClasses = module.classes;
|
|
70
|
+
const classes = declaredClasses === undefined ? [] : declaredClasses;
|
|
71
|
+
const declaredErrors = module.errors;
|
|
72
|
+
const errors = declaredErrors === undefined ? [] : declaredErrors;
|
|
73
|
+
if (!Array.isArray(records))
|
|
74
|
+
unsupportedCapability(language, "missing or invalid record declarations", module.location);
|
|
75
|
+
if (!Array.isArray(classes))
|
|
76
|
+
unsupportedCapability(language, "missing or invalid reference class declarations", module.location);
|
|
77
|
+
if (!Array.isArray(errors))
|
|
78
|
+
unsupportedCapability(language, "missing or invalid error declarations", module.location);
|
|
79
|
+
if (module.functions.length == 0 && (!options.program ||
|
|
80
|
+
records.length == 0 && classes.length == 0 && errors.length == 0 && module.entryPoint.body?.statements?.length == 0)) {
|
|
81
|
+
unsupportedCapability(language, "module without declarations or executable entry", module.location);
|
|
82
|
+
}
|
|
83
|
+
if (!task012Languages.has(language) && moduleHasTypeParameters(module)) {
|
|
84
|
+
unsupportedCapability(language, "Task 012 type parameters and generic declarations", module.location);
|
|
85
|
+
}
|
|
86
|
+
if (records.length > 0 && !task009Languages.has(language)) {
|
|
87
|
+
unsupportedCapability(language, "Task 009 closed records", records[0]?.location ?? module.location);
|
|
88
|
+
}
|
|
89
|
+
if (classes.length > 0 && !task033Languages.has(language)) {
|
|
90
|
+
unsupportedCapability(language, "Task 033 reference classes, methods, and constructors", classes[0]?.location ?? module.location);
|
|
91
|
+
}
|
|
92
|
+
if (!task011Languages.has(language))
|
|
93
|
+
rejectTypedErrors(module, language);
|
|
94
|
+
if (!task032Languages.has(language))
|
|
95
|
+
rejectConditionControlledLoops(module, language);
|
|
96
|
+
if (!task014Languages.has(language))
|
|
97
|
+
rejectOrderedMapCapability(module, language);
|
|
98
|
+
validateRecordTargets(records, module.functions, language, module.location);
|
|
99
|
+
validateReferenceClassTargets(classes, records, errors, module.functions, language, module.location);
|
|
100
|
+
if (!task008Languages.has(language))
|
|
101
|
+
rejectIterationStatements(module, language);
|
|
102
|
+
if (!task007Languages.has(language))
|
|
103
|
+
rejectOptionalTypes(module, language);
|
|
104
|
+
if (!task006Languages.has(language))
|
|
105
|
+
rejectCollectionTypes(module, language);
|
|
106
|
+
const loopOwners = collectLoopOwners(module, language);
|
|
107
|
+
for (const declaration of classes) {
|
|
108
|
+
validateBlock(declaration.constructor.body, language, declaration.constructor.location, { active: [], owner: declaration.constructor, owners: loopOwners }, new Set(), options.externalDeclarationIds);
|
|
109
|
+
for (const method of declaration.methods) {
|
|
110
|
+
validateBlock(method.body, language, method.location, { active: [], owner: method, owners: loopOwners }, new Set(), options.externalDeclarationIds);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
validateBlock(module.entryPoint.body, language, module.entryPoint.location, { active: [], owner: module.entryPoint, owners: loopOwners }, new Set(), options.externalDeclarationIds);
|
|
114
|
+
const declarationIds = new Set();
|
|
115
|
+
const declarationNames = new Set();
|
|
116
|
+
const targetDeclarationNames = new Set();
|
|
45
117
|
for (const functionDeclaration of module.functions) {
|
|
46
118
|
if (!functionDeclaration || typeof functionDeclaration != "object" || Array.isArray(functionDeclaration) ||
|
|
47
119
|
functionDeclaration.kind != "FunctionDeclaration" || !Array.isArray(functionDeclaration.parameters)) {
|
|
48
120
|
unsupportedCapability(language, "missing or invalid function declaration", module.location);
|
|
49
121
|
}
|
|
50
122
|
validateTargetBindingIdentifier(language, functionDeclaration.name, "function", functionDeclaration.location);
|
|
51
|
-
if (functionDeclaration.
|
|
123
|
+
if (declarationNames.has(functionDeclaration.name)) {
|
|
124
|
+
unsupportedCapability(language, `duplicate function '${functionDeclaration.name}'`, functionDeclaration.location);
|
|
125
|
+
}
|
|
126
|
+
declarationNames.add(functionDeclaration.name);
|
|
127
|
+
const targetDeclarationName = language == "php"
|
|
128
|
+
? functionDeclaration.name.replace(/[A-Z]/gu, (character) => character.toLowerCase())
|
|
129
|
+
: functionDeclaration.name;
|
|
130
|
+
if (targetDeclarationNames.has(targetDeclarationName)) {
|
|
131
|
+
unsupportedCapability(language, `target function-name collision '${functionDeclaration.name}'`, functionDeclaration.location);
|
|
132
|
+
}
|
|
133
|
+
targetDeclarationNames.add(targetDeclarationName);
|
|
134
|
+
if (typeof functionDeclaration.id != "string" || !/^(?:[a-z][a-z0-9._-]*#)?function:[0-9]+$/u.test(functionDeclaration.id) ||
|
|
135
|
+
declarationIds.has(functionDeclaration.id)) {
|
|
136
|
+
unsupportedCapability(language, "duplicate or invalid function declaration identity", functionDeclaration.location);
|
|
137
|
+
}
|
|
138
|
+
declarationIds.add(functionDeclaration.id);
|
|
139
|
+
validateTypeParameterTargets(functionDeclaration, language);
|
|
140
|
+
if (!task005Languages.has(language) && functionDeclaration.parameters.length != 2) {
|
|
52
141
|
unsupportedCapability(language, "function parameter count other than two", functionDeclaration.location);
|
|
53
142
|
}
|
|
54
|
-
|
|
143
|
+
if (!task005Languages.has(language) && functionDeclaration.returnType?.kind == "TypeReference" &&
|
|
144
|
+
functionDeclaration.returnType.name == "void") {
|
|
145
|
+
unsupportedCapability(language, "Task 005 void function return", functionDeclaration.location);
|
|
146
|
+
}
|
|
147
|
+
validateBlock(functionDeclaration.body, language, functionDeclaration.location, { active: [], owner: functionDeclaration, owners: loopOwners }, new Set(), options.externalDeclarationIds);
|
|
55
148
|
for (const parameter of functionDeclaration.parameters) {
|
|
56
149
|
if (!parameter || typeof parameter != "object" || Array.isArray(parameter) || parameter.kind != "Parameter") {
|
|
57
150
|
unsupportedCapability(language, "missing or invalid parameter", functionDeclaration.location);
|
|
@@ -59,92 +152,1110 @@ export function validateBackendModule(module, language) {
|
|
|
59
152
|
validateTargetBindingIdentifier(language, parameter.name, "parameter", parameter.location);
|
|
60
153
|
}
|
|
61
154
|
}
|
|
155
|
+
validateErrorTargets(errors, records, module.functions, language, module.location);
|
|
62
156
|
validateScaffoldingNames(module, language);
|
|
63
|
-
validateBackendTypes(module, language
|
|
157
|
+
validateBackendTypes(module, language, {
|
|
158
|
+
callEffects: options.visibleCallEffects,
|
|
159
|
+
classes: options.visibleClasses,
|
|
160
|
+
errors: options.visibleErrors,
|
|
161
|
+
functions: options.visibleFunctions,
|
|
162
|
+
records: options.visibleRecords
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Rejects Task 014 IR transactionally before a non-cohort target allocates output.
|
|
167
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
|
|
168
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
169
|
+
* @returns {void}
|
|
170
|
+
*/
|
|
171
|
+
function rejectOrderedMapCapability(module, language) {
|
|
172
|
+
const node = findOrderedMapNode(module);
|
|
173
|
+
if (node)
|
|
174
|
+
unsupportedCapability(language, "Task 014 ordered-map iteration", diagnosticLocation(node.location, module.location));
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Finds the first distinct ordered-map type, literal, or loop in parser-neutral IR.
|
|
178
|
+
* @param {unknown} value - Candidate subtree.
|
|
179
|
+
* @param {Set<object>} [seen] - Cycle protection.
|
|
180
|
+
* @returns {Record<string, unknown> | undefined} First Task 014 node.
|
|
181
|
+
*/
|
|
182
|
+
function findOrderedMapNode(value, seen = new Set()) {
|
|
183
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
184
|
+
return undefined;
|
|
185
|
+
seen.add(value);
|
|
186
|
+
if (!Array.isArray(value)) {
|
|
187
|
+
const candidate = /** @type {Record<string, unknown>} */ (value);
|
|
188
|
+
if (["OrderedMapType", "OrderedMapLiteral", "ForEachMapStatement"].includes(String(candidate.kind)))
|
|
189
|
+
return candidate;
|
|
190
|
+
}
|
|
191
|
+
for (const child of Array.isArray(value) ? value : Object.values(value)) {
|
|
192
|
+
const found = findOrderedMapNode(child, seen);
|
|
193
|
+
if (found)
|
|
194
|
+
return found;
|
|
195
|
+
}
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Rejects typed errors for a target outside the Task 011 cohort.
|
|
200
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
|
|
201
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
202
|
+
* @returns {void}
|
|
203
|
+
*/
|
|
204
|
+
function rejectTypedErrors(/** @type {import("../semantic/types.js").SemanticModule} */ module,
|
|
205
|
+
/** @type {import("../semantic/types.js").BackendLanguage} */ language) {
|
|
206
|
+
if ((module.errors ?? []).length > 0) {
|
|
207
|
+
unsupportedCapability(language, "Task 011 typed errors and handling", module.errors?.[0]?.location ?? module.location);
|
|
208
|
+
}
|
|
209
|
+
for (const declaration of module.functions)
|
|
210
|
+
rejectTypedErrorBlock(declaration?.body, language);
|
|
211
|
+
rejectTypedErrorBlock(module.entryPoint.body, language);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Finds typed-error statements without descending through malformed or cyclic blocks.
|
|
215
|
+
* @param {unknown} block - Candidate block.
|
|
216
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
217
|
+
* @param {Set<object>} [seen] - Visited blocks.
|
|
218
|
+
* @returns {void}
|
|
219
|
+
*/
|
|
220
|
+
function rejectTypedErrorBlock(/** @type {unknown} */ block,
|
|
221
|
+
/** @type {import("../semantic/types.js").BackendLanguage} */ language,
|
|
222
|
+
/** @type {Set<object>} */ seen = new Set()) {
|
|
223
|
+
if (!block || typeof block != "object" || Array.isArray(block) || seen.has(block))
|
|
224
|
+
return;
|
|
225
|
+
seen.add(block);
|
|
226
|
+
const statements = Reflect.get(block, "statements");
|
|
227
|
+
if (!Array.isArray(statements))
|
|
228
|
+
return;
|
|
229
|
+
for (const statement of statements) {
|
|
230
|
+
if (!statement || typeof statement != "object" || Array.isArray(statement))
|
|
231
|
+
continue;
|
|
232
|
+
if (Reflect.get(statement, "kind") == "RaiseStatement" || Reflect.get(statement, "kind") == "TryStatement") {
|
|
233
|
+
unsupportedCapability(language, "Task 011 typed errors and handling", diagnosticLocation(Reflect.get(statement, "location"), Reflect.get(block, "location")));
|
|
234
|
+
}
|
|
235
|
+
if (Reflect.get(statement, "kind") == "IfStatement") {
|
|
236
|
+
rejectTypedErrorBlock(Reflect.get(statement, "consequent"), language, seen);
|
|
237
|
+
rejectTypedErrorBlock(Reflect.get(statement, "alternate"), language, seen);
|
|
238
|
+
}
|
|
239
|
+
else if (["ForEachStatement", "ForEachMapStatement", "WhileStatement"].includes(String(Reflect.get(statement, "kind")))) {
|
|
240
|
+
rejectTypedErrorBlock(Reflect.get(statement, "body"), language, seen);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Validates target-visible nominal error declarations before emission.
|
|
246
|
+
* @param {import("../semantic/types.js").ErrorDeclaration[]} errors - Error declarations.
|
|
247
|
+
* @param {import("../semantic/types.js").RecordDeclaration[]} records - Record declarations.
|
|
248
|
+
* @param {import("../semantic/types.js").FunctionDeclaration[]} functions - Function declarations.
|
|
249
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
250
|
+
* @param {import("../semantic/types.js").SourceLocation} moduleLocation - Module location.
|
|
251
|
+
* @returns {void}
|
|
252
|
+
*/
|
|
253
|
+
function validateErrorTargets(
|
|
254
|
+
/** @type {import("../semantic/types.js").ErrorDeclaration[]} */ errors,
|
|
255
|
+
/** @type {import("../semantic/types.js").RecordDeclaration[]} */ records,
|
|
256
|
+
/** @type {import("../semantic/types.js").FunctionDeclaration[]} */ functions,
|
|
257
|
+
/** @type {import("../semantic/types.js").BackendLanguage} */ language,
|
|
258
|
+
/** @type {import("../semantic/types.js").SourceLocation} */ moduleLocation) {
|
|
259
|
+
const ids = new Set();
|
|
260
|
+
const names = new Set([...records, ...functions].map(({ name }) => language == "php" ? name.toLowerCase() : name));
|
|
261
|
+
const forbidden = language == "javascript" || language == "typescript" ? new Set(["Error", "AggregateError"]) :
|
|
262
|
+
language == "php" ? new Set(["Throwable", "Exception", "RuntimeException", "Error"]) :
|
|
263
|
+
language == "ruby" ? new Set(["Exception", "StandardError", "ScriptError", "SystemExit"]) :
|
|
264
|
+
language == "java" ? new Set(["Throwable", "Exception", "RuntimeException", "Error"]) : new Set();
|
|
265
|
+
for (let index = 0; index < errors.length; index += 1) {
|
|
266
|
+
const declaration = errors[index];
|
|
267
|
+
const location = diagnosticLocation(declaration?.location, moduleLocation);
|
|
268
|
+
const fields = declaration && typeof declaration == "object" && !Array.isArray(declaration)
|
|
269
|
+
? Object.keys(declaration).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
270
|
+
if (!declaration || typeof declaration != "object" || Array.isArray(declaration) ||
|
|
271
|
+
declaration.kind != "ErrorDeclaration" || fields != "id,kind,location,name") {
|
|
272
|
+
unsupportedCapability(language, "missing or invalid error declaration", location);
|
|
273
|
+
}
|
|
274
|
+
requireSemanticLocation(declaration.location, language, "error declaration location", moduleLocation);
|
|
275
|
+
validateTargetTypeIdentifier(language, declaration.name, declaration.location);
|
|
276
|
+
if ((declaration.id != `error:${index}` &&
|
|
277
|
+
!new RegExp(`^[a-z][a-z0-9._-]*#error:${index}$`, "u").test(declaration.id ?? "")) || ids.has(declaration.id)) {
|
|
278
|
+
unsupportedCapability(language, "duplicate or invalid error declaration identity", declaration.location);
|
|
279
|
+
}
|
|
280
|
+
const normalized = language == "php" ? declaration.name.toLowerCase() : declaration.name;
|
|
281
|
+
if (names.has(normalized) || forbidden.has(declaration.name)) {
|
|
282
|
+
unsupportedCapability(language, `error declaration collision '${declaration.name}'`, declaration.location);
|
|
283
|
+
}
|
|
284
|
+
ids.add(declaration.id);
|
|
285
|
+
names.add(normalized);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Validates every nominal record identifier, identity, field, and target collision before output allocation.
|
|
290
|
+
* @param {import("../semantic/types.js").RecordDeclaration[]} records - Candidate records.
|
|
291
|
+
* @param {import("../semantic/types.js").FunctionDeclaration[]} functions - Candidate functions.
|
|
292
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
293
|
+
* @param {import("../semantic/types.js").SourceLocation | undefined} moduleLocation - Module fallback location.
|
|
294
|
+
* @returns {void}
|
|
295
|
+
*/
|
|
296
|
+
function validateRecordTargets(records, functions, language, moduleLocation) {
|
|
297
|
+
const declarationIds = new Set();
|
|
298
|
+
const targetNames = new Set();
|
|
299
|
+
for (const declaration of functions) {
|
|
300
|
+
if (!declaration || typeof declaration != "object" || Array.isArray(declaration))
|
|
301
|
+
continue;
|
|
302
|
+
const name = Reflect.get(declaration, "name");
|
|
303
|
+
if (typeof name != "string")
|
|
304
|
+
continue;
|
|
305
|
+
targetNames.add(language == "php" ? name.toLowerCase() : name);
|
|
306
|
+
}
|
|
307
|
+
for (let recordIndex = 0; recordIndex < records.length; recordIndex += 1) {
|
|
308
|
+
const record = records[recordIndex];
|
|
309
|
+
const location = diagnosticLocation(record?.location, moduleLocation);
|
|
310
|
+
const recordKeys = record && typeof record == "object" && !Array.isArray(record)
|
|
311
|
+
? Object.keys(record).filter((key) => key != "sourceProvenance").sort().join(",")
|
|
312
|
+
: "";
|
|
313
|
+
if (!record || typeof record != "object" || Array.isArray(record) || record.kind != "RecordDeclaration" ||
|
|
314
|
+
!["fields,id,kind,location,name", "fields,id,kind,location,name,typeParameters"].includes(recordKeys) || !isDenseArray(record.fields)) {
|
|
315
|
+
unsupportedCapability(language, "missing or invalid record declaration", location);
|
|
316
|
+
}
|
|
317
|
+
requireSemanticLocation(record.location, language, "record declaration location", moduleLocation);
|
|
318
|
+
validateTargetTypeIdentifier(language, record.name, record.location);
|
|
319
|
+
if (typeof record.id != "string" || !new RegExp(`^(?:[a-z][a-z0-9._-]*#)?record:${recordIndex}$`, "u").test(record.id) ||
|
|
320
|
+
declarationIds.has(record.id)) {
|
|
321
|
+
unsupportedCapability(language, "duplicate or invalid record declaration identity", record.location);
|
|
322
|
+
}
|
|
323
|
+
declarationIds.add(record.id);
|
|
324
|
+
validateTypeParameterTargets(record, language);
|
|
325
|
+
const targetName = language == "php" ? record.name.toLowerCase() : record.name;
|
|
326
|
+
if (targetNames.has(targetName))
|
|
327
|
+
unsupportedCapability(language, `record declaration collision '${record.name}'`, record.location);
|
|
328
|
+
targetNames.add(targetName);
|
|
329
|
+
const fieldNames = new Set();
|
|
330
|
+
for (let fieldIndex = 0; fieldIndex < record.fields.length; fieldIndex += 1) {
|
|
331
|
+
const field = record.fields[fieldIndex];
|
|
332
|
+
const fieldLocation = diagnosticLocation(field?.location, record.location);
|
|
333
|
+
const fieldKeys = field && typeof field == "object" && !Array.isArray(field)
|
|
334
|
+
? Object.keys(field).filter((key) => key != "sourceProvenance").sort().join(",")
|
|
335
|
+
: "";
|
|
336
|
+
if (!field || typeof field != "object" || Array.isArray(field) || field.kind != "RecordField" ||
|
|
337
|
+
fieldKeys != "id,kind,location,name,type") {
|
|
338
|
+
unsupportedCapability(language, "missing or invalid record field", fieldLocation);
|
|
339
|
+
}
|
|
340
|
+
requireSemanticLocation(field.location, language, "record field location", record.location);
|
|
341
|
+
if (field.id != `${record.id}:field:${fieldIndex}`) {
|
|
342
|
+
unsupportedCapability(language, "duplicate or invalid record field identity", field.location);
|
|
343
|
+
}
|
|
344
|
+
validateTargetIdentifier(language, field.name, "record field", field.location);
|
|
345
|
+
const collision = language == "javascript" && ["constructor", "prototype", "__proto__"].includes(field.name) ||
|
|
346
|
+
language == "typescript" && ["constructor", "prototype", "__proto__"].includes(field.name) ||
|
|
347
|
+
language == "php" && field.name.toLowerCase().startsWith("__") ||
|
|
348
|
+
language == "ruby" && ["initialize", "freeze", "send", "public_send", "method", "singleton_class"].includes(field.name) ||
|
|
349
|
+
language == "java" && javaObjectInstanceMethodSignatures.has(`${field.name}()`);
|
|
350
|
+
if (collision)
|
|
351
|
+
unsupportedCapability(language, `record field collision '${field.name}'`, field.location);
|
|
352
|
+
const normalized = language == "php" ? field.name.toLowerCase() : field.name;
|
|
353
|
+
if (fieldNames.has(normalized))
|
|
354
|
+
unsupportedCapability(language, `duplicate target record field '${field.name}'`, field.location);
|
|
355
|
+
fieldNames.add(normalized);
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Validates the exact target-visible shape of every reference class before output allocation.
|
|
361
|
+
* @param {import("../semantic/types.js").ClassDeclaration[]} classes - Candidate classes.
|
|
362
|
+
* @param {import("../semantic/types.js").RecordDeclaration[]} records - Existing records.
|
|
363
|
+
* @param {import("../semantic/types.js").ErrorDeclaration[]} errors - Existing typed errors.
|
|
364
|
+
* @param {import("../semantic/types.js").FunctionDeclaration[]} functions - Existing functions.
|
|
365
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
366
|
+
* @param {import("../semantic/types.js").SourceLocation | undefined} moduleLocation - Fallback location.
|
|
367
|
+
* @returns {void}
|
|
368
|
+
*/
|
|
369
|
+
function validateReferenceClassTargets(classes, records, errors, functions, language, moduleLocation) {
|
|
370
|
+
const targetNames = new Set();
|
|
371
|
+
for (const declaration of [...records, ...errors, ...functions]) {
|
|
372
|
+
if (!declaration || typeof declaration != "object" || Array.isArray(declaration))
|
|
373
|
+
continue;
|
|
374
|
+
const name = Reflect.get(declaration, "name");
|
|
375
|
+
if (typeof name != "string")
|
|
376
|
+
continue;
|
|
377
|
+
targetNames.add(language == "php" ? name.toLowerCase() : name);
|
|
378
|
+
}
|
|
379
|
+
for (let classIndex = 0; classIndex < classes.length; classIndex += 1) {
|
|
380
|
+
const declaration = classes[classIndex];
|
|
381
|
+
const location = diagnosticLocation(declaration?.location, moduleLocation);
|
|
382
|
+
const keys = declaration && typeof declaration == "object" && !Array.isArray(declaration)
|
|
383
|
+
? Object.keys(declaration).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
384
|
+
if (!declaration || declaration.kind != "ClassDeclaration" ||
|
|
385
|
+
!["constructor,fields,id,kind,location,methods,name", "constructor,fields,id,kind,location,methods,name,ownership"].includes(keys) ||
|
|
386
|
+
!isDenseArray(declaration.fields) || declaration.fields.length == 0 || !isDenseArray(declaration.methods) ||
|
|
387
|
+
!new RegExp(`^(?:[a-z][a-z0-9._-]*#)?class:${classIndex}$`, "u").test(String(declaration.id))) {
|
|
388
|
+
unsupportedCapability(language, "missing or invalid reference class declaration", location);
|
|
389
|
+
}
|
|
390
|
+
if (declaration.ownership !== undefined && declaration.ownership?.kind != "ordinary" &&
|
|
391
|
+
(declaration.ownership?.kind != "ownedResource" || typeof declaration.ownership.fieldId != "string" ||
|
|
392
|
+
typeof declaration.ownership.resourceId != "string")) {
|
|
393
|
+
unsupportedCapability(language, "malformed reference class resource ownership", location);
|
|
394
|
+
}
|
|
395
|
+
const declarationLocation = requireSemanticLocation(declaration.location, language, "reference class declaration location", moduleLocation);
|
|
396
|
+
validateTargetTypeIdentifier(language, declaration.name, declarationLocation);
|
|
397
|
+
const targetName = language == "php" ? declaration.name.toLowerCase() : declaration.name;
|
|
398
|
+
if (targetNames.has(targetName))
|
|
399
|
+
unsupportedCapability(language, `reference class collision '${declaration.name}'`, declarationLocation);
|
|
400
|
+
targetNames.add(targetName);
|
|
401
|
+
const fieldNames = new Set();
|
|
402
|
+
for (let fieldIndex = 0; fieldIndex < declaration.fields.length; fieldIndex += 1) {
|
|
403
|
+
const field = declaration.fields[fieldIndex];
|
|
404
|
+
const fieldLocation = diagnosticLocation(field?.location, location);
|
|
405
|
+
const fieldKeys = field && typeof field == "object" && !Array.isArray(field)
|
|
406
|
+
? Object.keys(field).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
407
|
+
if (!field || field.kind != "PrivateField" || fieldKeys != "id,kind,location,name,type" ||
|
|
408
|
+
field.id != `${declaration.id}:field:${fieldIndex}`) {
|
|
409
|
+
unsupportedCapability(language, "missing or invalid private field", fieldLocation);
|
|
410
|
+
}
|
|
411
|
+
const exactFieldLocation = requireSemanticLocation(field.location, language, "private field location", declarationLocation);
|
|
412
|
+
validateTargetIdentifier(language, field.name, "private field", exactFieldLocation);
|
|
413
|
+
const normalized = language == "php" ? field.name.toLowerCase() : field.name;
|
|
414
|
+
if (fieldNames.has(normalized))
|
|
415
|
+
unsupportedCapability(language, `duplicate target private field '${field.name}'`, exactFieldLocation);
|
|
416
|
+
fieldNames.add(normalized);
|
|
417
|
+
}
|
|
418
|
+
const constructor = declaration.constructor;
|
|
419
|
+
const constructorLocation = diagnosticLocation(constructor?.location, location);
|
|
420
|
+
const constructorKeys = constructor && typeof constructor == "object" && !Array.isArray(constructor)
|
|
421
|
+
? Object.keys(constructor).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
422
|
+
if (!constructor || constructor.kind != "ConstructorDeclaration" ||
|
|
423
|
+
!["body,id,kind,location,parameters", "body,effects,failureIds,id,kind,location,parameters"].includes(constructorKeys) ||
|
|
424
|
+
constructor.id != `${declaration.id}:constructor` || !isDenseArray(constructor.parameters)) {
|
|
425
|
+
unsupportedCapability(language, "missing or invalid constructor declaration", constructorLocation);
|
|
426
|
+
}
|
|
427
|
+
const exactConstructorLocation = requireSemanticLocation(constructor.location, language, "constructor declaration location", declarationLocation);
|
|
428
|
+
validateReferenceClassParameters(constructor.parameters, "constructor", language, exactConstructorLocation);
|
|
429
|
+
const methodNames = new Set();
|
|
430
|
+
for (let methodIndex = 0; methodIndex < declaration.methods.length; methodIndex += 1) {
|
|
431
|
+
const method = declaration.methods[methodIndex];
|
|
432
|
+
const methodLocation = diagnosticLocation(method?.location, location);
|
|
433
|
+
const methodKeys = method && typeof method == "object" && !Array.isArray(method)
|
|
434
|
+
? Object.keys(method).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
435
|
+
if (!method || method.kind != "MethodDeclaration" ||
|
|
436
|
+
!["body,id,kind,location,name,parameters,returnType",
|
|
437
|
+
"body,effects,failureIds,id,kind,location,name,parameters,returnType"].includes(methodKeys) ||
|
|
438
|
+
method.id != `${declaration.id}:method:${methodIndex}` || !isDenseArray(method.parameters)) {
|
|
439
|
+
unsupportedCapability(language, "missing or invalid method declaration", methodLocation);
|
|
440
|
+
}
|
|
441
|
+
const exactMethodLocation = requireSemanticLocation(method.location, language, "method declaration location", declarationLocation);
|
|
442
|
+
const lifecycleName = language == "php" ? "__construct" : language == "ruby" ? "initialize" :
|
|
443
|
+
language == "javascript" || language == "typescript" ? "constructor" : undefined;
|
|
444
|
+
if (method.name == lifecycleName) {
|
|
445
|
+
unsupportedCapability(language, `reserved reference lifecycle method '${method.name}'`, exactMethodLocation);
|
|
446
|
+
}
|
|
447
|
+
const reservedHook = language == "php" ? /^__/u.test(method.name) :
|
|
448
|
+
language == "ruby" ? rubyReferenceMethodHooks.has(method.name) ||
|
|
449
|
+
typeof method.name == "string" && method.name.endsWith("=") :
|
|
450
|
+
language == "java" ? javaReferenceMethodHooks.has(method.name) :
|
|
451
|
+
language == "javascript" || language == "typescript" ? javascriptReferenceMethodHooks.has(method.name) : false;
|
|
452
|
+
if (reservedHook)
|
|
453
|
+
unsupportedCapability(language, `reserved reference method '${method.name}'`, exactMethodLocation);
|
|
454
|
+
if (language == "ruby") {
|
|
455
|
+
if (typeof method.name != "string" || !/^[A-Za-z_][A-Za-z0-9_]*[!?=]?$/u.test(method.name)) {
|
|
456
|
+
unsupportedCapability(language, `method identifier '${String(method.name)}'`, exactMethodLocation);
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
else
|
|
460
|
+
validateTargetIdentifier(language, method.name, "method", exactMethodLocation);
|
|
461
|
+
const normalized = language == "php" ? method.name.toLowerCase() : method.name;
|
|
462
|
+
if (methodNames.has(normalized))
|
|
463
|
+
unsupportedCapability(language, `duplicate target method '${method.name}'`, exactMethodLocation);
|
|
464
|
+
if (language == "typescript" && fieldNames.has(normalized)) {
|
|
465
|
+
unsupportedCapability(language, `target class member collision '${method.name}'`, exactMethodLocation);
|
|
466
|
+
}
|
|
467
|
+
methodNames.add(normalized);
|
|
468
|
+
validateReferenceClassParameters(method.parameters, "method", language, exactMethodLocation);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Validates one reference callable's exact parameter shape and target names.
|
|
474
|
+
* @param {import("../semantic/types.js").Parameter[]} parameters - Candidate parameters.
|
|
475
|
+
* @param {"constructor" | "method"} owner - Callable kind.
|
|
476
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
477
|
+
* @param {import("../semantic/types.js").SourceLocation | undefined} ownerLocation - Fallback location.
|
|
478
|
+
* @returns {void}
|
|
479
|
+
*/
|
|
480
|
+
function validateReferenceClassParameters(parameters, owner, language, ownerLocation) {
|
|
481
|
+
for (const parameter of parameters) {
|
|
482
|
+
const location = diagnosticLocation(parameter?.location, ownerLocation);
|
|
483
|
+
const keys = parameter && typeof parameter == "object" && !Array.isArray(parameter)
|
|
484
|
+
? Object.keys(parameter).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
485
|
+
if (!parameter || parameter.kind != "Parameter" || keys != "kind,location,name,type") {
|
|
486
|
+
unsupportedCapability(language, `missing or invalid ${owner} parameter`, location);
|
|
487
|
+
}
|
|
488
|
+
const exactLocation = requireSemanticLocation(parameter.location, language, `${owner} parameter location`, ownerLocation);
|
|
489
|
+
validateTargetBindingIdentifier(language, parameter.name, "parameter", exactLocation);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
/**
|
|
493
|
+
* Validates one declaration's target-visible type-parameter names and identities.
|
|
494
|
+
* @param {import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").RecordDeclaration} declaration - Owner.
|
|
495
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
496
|
+
* @returns {void}
|
|
497
|
+
*/
|
|
498
|
+
function validateTypeParameterTargets(declaration, language) {
|
|
499
|
+
if (declaration.typeParameters === undefined)
|
|
500
|
+
return;
|
|
501
|
+
if (!isDenseArray(declaration.typeParameters)) {
|
|
502
|
+
unsupportedCapability(language, "missing or invalid type parameter declarations", declaration.location);
|
|
503
|
+
}
|
|
504
|
+
const names = new Set();
|
|
505
|
+
/**
|
|
506
|
+
* Normalizes a type/value spelling for target collision checks.
|
|
507
|
+
* @param {string} name - Candidate target name.
|
|
508
|
+
* @returns {string} Target comparison key.
|
|
509
|
+
*/
|
|
510
|
+
const targetKey = (name) => language == "php" ? name.toLowerCase() : name;
|
|
511
|
+
const valueNames = new Set([
|
|
512
|
+
declaration.name,
|
|
513
|
+
...(declaration.kind == "FunctionDeclaration" ? declaration.parameters : declaration.fields).map(({ name }) => name)
|
|
514
|
+
].map(targetKey));
|
|
515
|
+
for (let index = 0; index < declaration.typeParameters.length; index += 1) {
|
|
516
|
+
const parameter = declaration.typeParameters[index];
|
|
517
|
+
const keys = parameter && typeof parameter == "object" && !Array.isArray(parameter)
|
|
518
|
+
? Object.keys(parameter).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
519
|
+
if (!parameter || parameter.kind != "TypeParameter" || keys != "id,kind,location,name" ||
|
|
520
|
+
parameter.id != `${declaration.id}:type:${index}`) {
|
|
521
|
+
unsupportedCapability(language, "missing or invalid type parameter declaration", parameter?.location ?? declaration.location);
|
|
522
|
+
}
|
|
523
|
+
requireSemanticLocation(parameter.location, language, "type parameter location", declaration.location);
|
|
524
|
+
validateTargetTypeIdentifier(language, parameter.name, parameter.location);
|
|
525
|
+
const normalized = targetKey(parameter.name);
|
|
526
|
+
if (names.has(normalized) || valueNames.has(normalized)) {
|
|
527
|
+
unsupportedCapability(language, `target type parameter collision '${parameter.name}'`, parameter.location);
|
|
528
|
+
}
|
|
529
|
+
names.add(normalized);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Detects Task 012 IR before a non-cohort backend reaches older feature checks.
|
|
534
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
|
|
535
|
+
* @returns {boolean} Whether generic declarations are present.
|
|
536
|
+
*/
|
|
537
|
+
function moduleHasTypeParameters(module) {
|
|
538
|
+
return [...module.records ?? [], ...module.functions].some((declaration) => Array.isArray(declaration?.typeParameters) && declaration.typeParameters.length > 0);
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Rejects Task 008 statements before a non-cohort backend reaches collection-type checks.
|
|
542
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
|
|
543
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
544
|
+
* @returns {void}
|
|
545
|
+
*/
|
|
546
|
+
function rejectIterationStatements(module, language) {
|
|
547
|
+
for (const declaration of module.functions) {
|
|
548
|
+
rejectBlockIteration(declaration && typeof declaration == "object" && !Array.isArray(declaration)
|
|
549
|
+
? Reflect.get(declaration, "body")
|
|
550
|
+
: undefined, language);
|
|
551
|
+
}
|
|
552
|
+
rejectBlockIteration(module.entryPoint.body, language);
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Rejects Task 032 IR before a non-cohort backend allocates output.
|
|
556
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate module.
|
|
557
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
558
|
+
* @returns {void}
|
|
559
|
+
*/
|
|
560
|
+
function rejectConditionControlledLoops(module, language) {
|
|
561
|
+
for (const declaration of module.functions) {
|
|
562
|
+
rejectBlockConditionLoop(declaration && typeof declaration == "object" && !Array.isArray(declaration)
|
|
563
|
+
? Reflect.get(declaration, "body")
|
|
564
|
+
: undefined, language);
|
|
565
|
+
}
|
|
566
|
+
rejectBlockConditionLoop(module.entryPoint.body, language);
|
|
567
|
+
}
|
|
568
|
+
/**
|
|
569
|
+
* Finds a condition-controlled loop without descending through malformed or cyclic containers.
|
|
570
|
+
* @param {unknown} block - Candidate block.
|
|
571
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
572
|
+
* @param {Set<object>} [seen] - Visited containers.
|
|
573
|
+
* @returns {void}
|
|
574
|
+
*/
|
|
575
|
+
function rejectBlockConditionLoop(block, language, seen = new Set()) {
|
|
576
|
+
if (!block || typeof block != "object" || Array.isArray(block) || seen.has(block))
|
|
577
|
+
return;
|
|
578
|
+
seen.add(block);
|
|
579
|
+
const statements = Reflect.get(block, "statements");
|
|
580
|
+
if (!Array.isArray(statements))
|
|
581
|
+
return;
|
|
582
|
+
for (const statement of statements) {
|
|
583
|
+
if (!statement || typeof statement != "object" || Array.isArray(statement))
|
|
584
|
+
continue;
|
|
585
|
+
const kind = Reflect.get(statement, "kind");
|
|
586
|
+
const location = diagnosticLocation(Reflect.get(statement, "location"), Reflect.get(block, "location"));
|
|
587
|
+
if (kind == "WhileStatement")
|
|
588
|
+
unsupportedCapability(language, "Task 032 condition-controlled loop", location);
|
|
589
|
+
if (kind == "IfStatement") {
|
|
590
|
+
rejectBlockConditionLoop(Reflect.get(statement, "consequent"), language, seen);
|
|
591
|
+
rejectBlockConditionLoop(Reflect.get(statement, "alternate"), language, seen);
|
|
592
|
+
}
|
|
593
|
+
else if (["ForEachStatement", "ForEachMapStatement", "WhileStatement"].includes(String(kind))) {
|
|
594
|
+
rejectBlockConditionLoop(Reflect.get(statement, "body"), language, seen);
|
|
595
|
+
}
|
|
596
|
+
else if (kind == "TryStatement") {
|
|
597
|
+
rejectBlockConditionLoop(Reflect.get(statement, "body"), language, seen);
|
|
598
|
+
rejectBlockConditionLoop(Reflect.get(statement, "catchBody"), language, seen);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Finds a Task 008 node without descending through malformed or cyclic containers.
|
|
604
|
+
* @param {unknown} block - Candidate block.
|
|
605
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
606
|
+
* @param {Set<object>} [seen] - Visited containers.
|
|
607
|
+
* @returns {void}
|
|
608
|
+
*/
|
|
609
|
+
function rejectBlockIteration(block, language, seen = new Set()) {
|
|
610
|
+
if (!block || typeof block != "object" || Array.isArray(block) || seen.has(block))
|
|
611
|
+
return;
|
|
612
|
+
seen.add(block);
|
|
613
|
+
const statements = Reflect.get(block, "statements");
|
|
614
|
+
if (!Array.isArray(statements))
|
|
615
|
+
return;
|
|
616
|
+
for (const statement of statements) {
|
|
617
|
+
if (!statement || typeof statement != "object" || Array.isArray(statement))
|
|
618
|
+
continue;
|
|
619
|
+
const kind = Reflect.get(statement, "kind");
|
|
620
|
+
const location = diagnosticLocation(Reflect.get(statement, "location"), Reflect.get(block, "location"));
|
|
621
|
+
if (["ForEachStatement", "ForEachMapStatement", "BreakStatement", "ContinueStatement"].includes(kind)) {
|
|
622
|
+
unsupportedCapability(language, "Task 008 ordered list iteration", location);
|
|
623
|
+
}
|
|
624
|
+
if (kind == "IfStatement") {
|
|
625
|
+
rejectBlockIteration(Reflect.get(statement, "consequent"), language, seen);
|
|
626
|
+
rejectBlockIteration(Reflect.get(statement, "alternate"), language, seen);
|
|
627
|
+
}
|
|
628
|
+
else if (kind == "TryStatement") {
|
|
629
|
+
rejectBlockIteration(Reflect.get(statement, "body"), language, seen);
|
|
630
|
+
rejectBlockIteration(Reflect.get(statement, "catchBody"), language, seen);
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Rejects Task 007 optional types before a non-cohort emitter allocates output.
|
|
636
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate semantic module.
|
|
637
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
638
|
+
* @returns {void}
|
|
639
|
+
*/
|
|
640
|
+
function rejectOptionalTypes(module, language) {
|
|
641
|
+
for (const declaration of module.functions) {
|
|
642
|
+
if (!declaration || typeof declaration != "object" || Array.isArray(declaration))
|
|
643
|
+
continue;
|
|
644
|
+
const location = Reflect.get(declaration, "location") ?? module.location;
|
|
645
|
+
if (containsOptionalType(Reflect.get(declaration, "returnType"))) {
|
|
646
|
+
unsupportedCapability(language, "Task 007 optional return type", location);
|
|
647
|
+
}
|
|
648
|
+
for (const parameter of Array.isArray(Reflect.get(declaration, "parameters")) ? Reflect.get(declaration, "parameters") : []) {
|
|
649
|
+
if (containsOptionalType(parameter?.type)) {
|
|
650
|
+
unsupportedCapability(language, "Task 007 optional parameter type", parameter.location ?? location);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
rejectBlockOptionalTypes(Reflect.get(declaration, "body"), language);
|
|
654
|
+
}
|
|
655
|
+
rejectBlockOptionalTypes(module.entryPoint.body, language);
|
|
656
|
+
}
|
|
657
|
+
/**
|
|
658
|
+
* Rejects optional local types recursively in one candidate block.
|
|
659
|
+
* @param {unknown} block - Candidate block.
|
|
660
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
661
|
+
* @returns {void}
|
|
662
|
+
*/
|
|
663
|
+
function rejectBlockOptionalTypes(block, language) {
|
|
664
|
+
if (!block || typeof block != "object" || Array.isArray(block) || !Array.isArray(Reflect.get(block, "statements")))
|
|
665
|
+
return;
|
|
666
|
+
for (const statement of Reflect.get(block, "statements")) {
|
|
667
|
+
if (!statement || typeof statement != "object" || Array.isArray(statement))
|
|
668
|
+
continue;
|
|
669
|
+
if (statement.kind == "LocalDeclaration" && containsOptionalType(statement.type)) {
|
|
670
|
+
unsupportedCapability(language, "Task 007 optional local type", statement.location);
|
|
671
|
+
}
|
|
672
|
+
if (statement.kind == "IfStatement") {
|
|
673
|
+
rejectBlockOptionalTypes(statement.consequent, language);
|
|
674
|
+
if (statement.alternate)
|
|
675
|
+
rejectBlockOptionalTypes(statement.alternate, language);
|
|
676
|
+
}
|
|
677
|
+
if (statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement") {
|
|
678
|
+
if (containsOptionalType(statement.valueBinding?.type)) {
|
|
679
|
+
unsupportedCapability(language, "Task 007 optional iteration binding type", statement.valueBinding.location ?? statement.location);
|
|
680
|
+
}
|
|
681
|
+
rejectBlockOptionalTypes(statement.body, language);
|
|
682
|
+
}
|
|
683
|
+
if (statement.kind == "WhileStatement")
|
|
684
|
+
rejectBlockOptionalTypes(statement.body, language);
|
|
685
|
+
if (statement.kind == "TryStatement") {
|
|
686
|
+
rejectBlockOptionalTypes(statement.body, language);
|
|
687
|
+
rejectBlockOptionalTypes(statement.catchBody, language);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Checks one bounded recursive semantic type for an optional node.
|
|
693
|
+
* @param {unknown} type - Candidate type.
|
|
694
|
+
* @param {Set<object>} [seen] - Cycle protection.
|
|
695
|
+
* @returns {boolean} Whether an optional type occurs.
|
|
696
|
+
*/
|
|
697
|
+
function containsOptionalType(type, seen = new Set()) {
|
|
698
|
+
if (!type || typeof type != "object" || Array.isArray(type) || seen.has(type))
|
|
699
|
+
return false;
|
|
700
|
+
seen.add(type);
|
|
701
|
+
const kind = Reflect.get(type, "kind");
|
|
702
|
+
if (kind == "OptionalType")
|
|
703
|
+
return true;
|
|
704
|
+
if (kind == "ListType")
|
|
705
|
+
return containsOptionalType(Reflect.get(type, "elementType"), seen);
|
|
706
|
+
if (kind == "MapType" || kind == "OrderedMapType")
|
|
707
|
+
return containsOptionalType(Reflect.get(type, "keyType"), seen) ||
|
|
708
|
+
containsOptionalType(Reflect.get(type, "valueType"), seen);
|
|
709
|
+
return false;
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* Rejects Task 006 types before a registered non-cohort emitter can allocate an artifact.
|
|
713
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
|
|
714
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
715
|
+
* @returns {void}
|
|
716
|
+
*/
|
|
717
|
+
function rejectCollectionTypes(module, language) {
|
|
718
|
+
for (const declaration of module.functions) {
|
|
719
|
+
if (!declaration || typeof declaration != "object" || Array.isArray(declaration))
|
|
720
|
+
continue;
|
|
721
|
+
const location = Reflect.get(declaration, "location") ?? module.location;
|
|
722
|
+
const returnType = Reflect.get(declaration, "returnType");
|
|
723
|
+
if (isCollectionType(returnType)) {
|
|
724
|
+
unsupportedCapability(language, "Task 006 immutable collection return type", location);
|
|
725
|
+
}
|
|
726
|
+
const parameters = Reflect.get(declaration, "parameters");
|
|
727
|
+
for (const parameter of Array.isArray(parameters) ? parameters : []) {
|
|
728
|
+
if (isCollectionType(parameter?.type))
|
|
729
|
+
unsupportedCapability(language, "Task 006 immutable collection parameter type", parameter.location ?? location);
|
|
730
|
+
}
|
|
731
|
+
rejectBlockCollectionTypes(Reflect.get(declaration, "body"), language);
|
|
732
|
+
}
|
|
733
|
+
rejectBlockCollectionTypes(module.entryPoint.body, language);
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Rejects collection local types recursively in one block.
|
|
737
|
+
* @param {unknown} block - Candidate semantic block.
|
|
738
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target identity.
|
|
739
|
+
* @returns {void}
|
|
740
|
+
*/
|
|
741
|
+
function rejectBlockCollectionTypes(block, language) {
|
|
742
|
+
if (!block || typeof block != "object" || Array.isArray(block) || !Array.isArray(Reflect.get(block, "statements")))
|
|
743
|
+
return;
|
|
744
|
+
for (const statement of Reflect.get(block, "statements")) {
|
|
745
|
+
if (!statement || typeof statement != "object" || Array.isArray(statement))
|
|
746
|
+
continue;
|
|
747
|
+
if (statement.kind == "LocalDeclaration" && isCollectionType(statement.type)) {
|
|
748
|
+
unsupportedCapability(language, "Task 006 immutable collection local type", statement.location);
|
|
749
|
+
}
|
|
750
|
+
if (statement.kind == "IfStatement") {
|
|
751
|
+
rejectBlockCollectionTypes(statement.consequent, language);
|
|
752
|
+
if (statement.alternate)
|
|
753
|
+
rejectBlockCollectionTypes(statement.alternate, language);
|
|
754
|
+
}
|
|
755
|
+
if (statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement") {
|
|
756
|
+
if (isCollectionType(statement.valueBinding?.type)) {
|
|
757
|
+
unsupportedCapability(language, "Task 006 immutable collection iteration binding type", statement.valueBinding.location ?? statement.location);
|
|
758
|
+
}
|
|
759
|
+
rejectBlockCollectionTypes(statement.body, language);
|
|
760
|
+
}
|
|
761
|
+
if (statement.kind == "WhileStatement")
|
|
762
|
+
rejectBlockCollectionTypes(statement.body, language);
|
|
763
|
+
if (statement.kind == "TryStatement") {
|
|
764
|
+
rejectBlockCollectionTypes(statement.body, language);
|
|
765
|
+
rejectBlockCollectionTypes(statement.catchBody, language);
|
|
766
|
+
}
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
/**
|
|
770
|
+
* Checks a possible recursive collection type without traversing malformed children.
|
|
771
|
+
* @param {unknown} type - Candidate type.
|
|
772
|
+
* @returns {boolean} Whether the outer type is a collection.
|
|
773
|
+
*/
|
|
774
|
+
function isCollectionType(type) {
|
|
775
|
+
return Boolean(type && typeof type == "object" && !Array.isArray(type) &&
|
|
776
|
+
(["ListType", "MapType", "OrderedMapType"].includes(String(Reflect.get(type, "kind")))));
|
|
64
777
|
}
|
|
65
778
|
/**
|
|
66
779
|
* Rejects semantic names that would capture syntax owned by one backend emitter.
|
|
67
780
|
* @param {import("../semantic/types.js").SemanticModule} module - Semantic module.
|
|
68
|
-
* @param {import("../semantic/types.js").
|
|
781
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
69
782
|
* @returns {void}
|
|
70
783
|
*/
|
|
71
784
|
function validateScaffoldingNames(module, language) {
|
|
785
|
+
validateRecordConstructorNames(module, language);
|
|
786
|
+
const needsNativeMap = ["javascript", "typescript"].includes(language) &&
|
|
787
|
+
(moduleContainsExpressionKind(module, "MapLiteral") || moduleContainsExpressionKind(module, "OrderedMapLiteral"));
|
|
788
|
+
const needsPhpCount = language == "php" && moduleContainsExpressionKind(module, "CollectionSizeExpression");
|
|
789
|
+
const javascriptOwnedNames = new Set(["console", ...(needsNativeMap ? ["Map"] : [])]);
|
|
72
790
|
const ownedEntryNames = language == "go" ? new Set(["fmt", "int64", "bool", "string", "true", "false"]) :
|
|
73
791
|
language == "csharp" ? new Set(["System"]) : language == "java" ? new Set(["args", "System"]) :
|
|
74
|
-
["javascript", "typescript"].includes(language) ?
|
|
792
|
+
["javascript", "typescript"].includes(language) ? javascriptOwnedNames : new Set();
|
|
75
793
|
const ownedPrintReceiverNames = language == "go" ? new Set(["fmt", "int64", "bool", "string", "true", "false"]) :
|
|
76
794
|
language == "csharp" || language == "java" ? new Set(["System"]) :
|
|
77
|
-
["javascript", "typescript"].includes(language) ?
|
|
795
|
+
["javascript", "typescript"].includes(language) ? javascriptOwnedNames : new Set();
|
|
78
796
|
const ownedCallableNames = language == "go" ? new Set(["main", "init", "fmt", "int64", "bool", "string", "true", "false"]) :
|
|
79
797
|
language == "csharp" ? new Set([
|
|
80
798
|
"Equals", "Finalize", "GetHashCode", "GetType", "Main", "MemberwiseClone", "Program", "ReferenceEquals", "System", "ToString"
|
|
81
799
|
]) :
|
|
82
|
-
|
|
83
|
-
|
|
800
|
+
language == "java" ? new Set(["main"]) :
|
|
801
|
+
["javascript", "typescript"].includes(language) ? javascriptOwnedNames :
|
|
802
|
+
needsPhpCount ? new Set(["count"]) :
|
|
803
|
+
language == "ruby" ? new Set(["puts", "send", "public_send", "__send__"]) : new Set();
|
|
804
|
+
/**
|
|
805
|
+
* Protects print/factory spellings inside one callable scope.
|
|
806
|
+
* @param {import("../semantic/types.js").Parameter[]} parameters - Callable parameters.
|
|
807
|
+
* @param {import("../semantic/types.js").Block} body - Callable body.
|
|
808
|
+
* @param {"function" | "constructor" | "method"} owner - Diagnostic owner.
|
|
809
|
+
*/
|
|
810
|
+
const validateCallableBindings = (parameters, body, owner) => {
|
|
811
|
+
for (const parameter of parameters) {
|
|
812
|
+
if (ownedPrintReceiverNames.has(parameter.name)) {
|
|
813
|
+
unsupportedCapability(language, `${owner} parameter '${parameter.name}' captures backend scaffolding`, parameter.location);
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
for (const statement of allStatements(body)) {
|
|
817
|
+
if (statement.kind == "LocalDeclaration" && ownedPrintReceiverNames.has(statement.name)) {
|
|
818
|
+
unsupportedCapability(language, `${owner} local '${statement.name}' captures backend scaffolding`, statement.location);
|
|
819
|
+
}
|
|
820
|
+
if (statement.kind == "ForEachStatement" && ownedPrintReceiverNames.has(statement.valueBinding.name)) {
|
|
821
|
+
unsupportedCapability(language, `${owner} iteration binding '${statement.valueBinding.name}' captures backend scaffolding`, statement.valueBinding.location);
|
|
822
|
+
}
|
|
823
|
+
if (statement.kind == "ForEachMapStatement") {
|
|
824
|
+
for (const binding of [statement.keyBinding, statement.valueBinding]) {
|
|
825
|
+
if (ownedPrintReceiverNames.has(binding.name)) {
|
|
826
|
+
unsupportedCapability(language, `${owner} iteration binding '${binding.name}' captures backend scaffolding`, binding.location);
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
if (statement.kind == "TryStatement" && ownedPrintReceiverNames.has(statement.catchBinding.name)) {
|
|
831
|
+
unsupportedCapability(language, `${owner} catch binding '${statement.catchBinding.name}' captures backend scaffolding`, statement.catchBinding.location);
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
};
|
|
84
835
|
for (const statement of allStatements(module.entryPoint.body)) {
|
|
85
836
|
if (statement.kind == "LocalDeclaration" && ownedEntryNames.has(statement.name)) {
|
|
86
837
|
unsupportedCapability(language, `entry local '${statement.name}' captures backend scaffolding`, statement.location);
|
|
87
838
|
}
|
|
839
|
+
if (statement.kind == "ForEachStatement" && ownedEntryNames.has(statement.valueBinding.name)) {
|
|
840
|
+
unsupportedCapability(language, `entry iteration binding '${statement.valueBinding.name}' captures backend scaffolding`, statement.valueBinding.location);
|
|
841
|
+
}
|
|
842
|
+
if (statement.kind == "ForEachMapStatement") {
|
|
843
|
+
for (const binding of [statement.keyBinding, statement.valueBinding]) {
|
|
844
|
+
if (ownedEntryNames.has(binding.name)) {
|
|
845
|
+
unsupportedCapability(language, `entry iteration binding '${binding.name}' captures backend scaffolding`, binding.location);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
if (statement.kind == "TryStatement" && ownedEntryNames.has(statement.catchBinding.name)) {
|
|
850
|
+
unsupportedCapability(language, `entry catch binding '${statement.catchBinding.name}' captures backend scaffolding`, statement.catchBinding.location);
|
|
851
|
+
}
|
|
88
852
|
}
|
|
89
853
|
for (const declaration of module.functions) {
|
|
90
|
-
|
|
91
|
-
|
|
854
|
+
const targetName = language == "php" ? declaration.name.toLowerCase() : declaration.name;
|
|
855
|
+
if (ownedCallableNames.has(targetName)) {
|
|
856
|
+
unsupportedCapability(language, `function '${declaration.name}' captures backend scaffolding`, declarationNameLocation(declaration));
|
|
92
857
|
}
|
|
858
|
+
if (language == "java") {
|
|
859
|
+
const signature = emittedJavaFunctionSignature(declaration);
|
|
860
|
+
if (signature && javaObjectInstanceMethodSignatures.has(signature)) {
|
|
861
|
+
unsupportedCapability(language, `function '${signature}' conflicts with an inherited java.lang.Object instance method`, declarationNameLocation(declaration));
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
validateCallableBindings(declaration.parameters, declaration.body, "function");
|
|
865
|
+
}
|
|
866
|
+
for (const declaration of module.classes ?? []) {
|
|
867
|
+
validateCallableBindings(declaration.constructor.parameters, declaration.constructor.body, "constructor");
|
|
868
|
+
for (const method of declaration.methods)
|
|
869
|
+
validateCallableBindings(method.parameters, method.body, "method");
|
|
870
|
+
}
|
|
871
|
+
if (language == "java")
|
|
872
|
+
validateJavaUtilFactoryNames(module);
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* Rejects JavaScript-family lexical bindings that can capture emitted bare record constructor names.
|
|
876
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Validated-shape semantic module.
|
|
877
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
878
|
+
* @returns {void}
|
|
879
|
+
*/
|
|
880
|
+
function validateRecordConstructorNames(module, language) {
|
|
881
|
+
if (language != "javascript" && language != "typescript")
|
|
882
|
+
return;
|
|
883
|
+
const recordNames = new Set([
|
|
884
|
+
...(module.records ?? []).map((record) => record.name),
|
|
885
|
+
...(module.classes ?? []).map((declaration) => declaration.name),
|
|
886
|
+
...(module.errors ?? []).map((error) => error.name)
|
|
887
|
+
]);
|
|
888
|
+
/**
|
|
889
|
+
* Checks declarations nested beneath one owning block.
|
|
890
|
+
* @param {import("../semantic/types.js").Block} block - Block to inspect.
|
|
891
|
+
* @param {"entry" | "function" | "constructor" | "method"} owner - Owning scope kind.
|
|
892
|
+
* @returns {void}
|
|
893
|
+
*/
|
|
894
|
+
const validateBlockNames = (block, owner) => {
|
|
895
|
+
for (const statement of allStatements(block)) {
|
|
896
|
+
if (statement.kind == "LocalDeclaration" && recordNames.has(statement.name)) {
|
|
897
|
+
unsupportedCapability(language, `${owner} local '${statement.name}' captures record constructor`, bindingNameLocation(statement));
|
|
898
|
+
}
|
|
899
|
+
if (statement.kind == "ForEachStatement" && recordNames.has(statement.valueBinding.name)) {
|
|
900
|
+
unsupportedCapability(language, `${owner} iteration binding '${statement.valueBinding.name}' captures record constructor`, bindingNameLocation(statement.valueBinding));
|
|
901
|
+
}
|
|
902
|
+
if (statement.kind == "ForEachMapStatement") {
|
|
903
|
+
for (const binding of [statement.keyBinding, statement.valueBinding]) {
|
|
904
|
+
if (recordNames.has(binding.name)) {
|
|
905
|
+
unsupportedCapability(language, `${owner} iteration binding '${binding.name}' captures record constructor`, bindingNameLocation(binding));
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
if (statement.kind == "TryStatement" && recordNames.has(statement.catchBinding.name)) {
|
|
910
|
+
unsupportedCapability(language, `${owner} catch binding '${statement.catchBinding.name}' captures nominal constructor`, bindingNameLocation(statement.catchBinding));
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
};
|
|
914
|
+
validateBlockNames(module.entryPoint.body, "entry");
|
|
915
|
+
for (const declaration of module.functions) {
|
|
93
916
|
for (const parameter of declaration.parameters) {
|
|
94
|
-
if (
|
|
95
|
-
unsupportedCapability(language, `function parameter '${parameter.name}' captures
|
|
917
|
+
if (recordNames.has(parameter.name)) {
|
|
918
|
+
unsupportedCapability(language, `function parameter '${parameter.name}' captures record constructor`, bindingNameLocation(parameter));
|
|
96
919
|
}
|
|
97
920
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
921
|
+
validateBlockNames(declaration.body, "function");
|
|
922
|
+
}
|
|
923
|
+
for (const declaration of module.classes ?? []) {
|
|
924
|
+
for (const parameter of declaration.constructor.parameters) {
|
|
925
|
+
if (recordNames.has(parameter.name)) {
|
|
926
|
+
unsupportedCapability(language, `constructor parameter '${parameter.name}' captures nominal constructor`, bindingNameLocation(parameter));
|
|
101
927
|
}
|
|
102
928
|
}
|
|
929
|
+
validateBlockNames(declaration.constructor.body, "constructor");
|
|
930
|
+
for (const method of declaration.methods) {
|
|
931
|
+
for (const parameter of method.parameters) {
|
|
932
|
+
if (recordNames.has(parameter.name)) {
|
|
933
|
+
unsupportedCapability(language, `method parameter '${parameter.name}' captures nominal constructor`, bindingNameLocation(parameter));
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
validateBlockNames(method.body, "method");
|
|
937
|
+
}
|
|
103
938
|
}
|
|
104
939
|
}
|
|
940
|
+
/**
|
|
941
|
+
* Rejects lexical bindings that would capture Java's package qualifier in emitted collection factories.
|
|
942
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Validated semantic module.
|
|
943
|
+
* @returns {void}
|
|
944
|
+
*/
|
|
945
|
+
function validateJavaUtilFactoryNames(module) {
|
|
946
|
+
/**
|
|
947
|
+
* Walks one lexical block while retaining only a currently visible capture.
|
|
948
|
+
* @param {import("../semantic/types.js").Block} block - Block to inspect in semantic order.
|
|
949
|
+
* @param {{detail: string, location: import("../semantic/types.js").SourceLocation} | undefined} inherited - Visible capture.
|
|
950
|
+
* @param {"entry" | "function" | "constructor" | "method"} owner - Owning scope kind.
|
|
951
|
+
* @returns {void}
|
|
952
|
+
*/
|
|
953
|
+
const validateBlockNames = (block, inherited, owner) => {
|
|
954
|
+
let capture = inherited;
|
|
955
|
+
for (const statement of block.statements) {
|
|
956
|
+
if (statement.kind == "LocalDeclaration" && statement.name == "java") {
|
|
957
|
+
capture = {
|
|
958
|
+
detail: `${owner} local 'java' captures java.util factory syntax`,
|
|
959
|
+
location: statement.location
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
963
|
+
statement.kind == "WhileStatement" ? statement.condition :
|
|
964
|
+
statement.kind == "ForEachStatement" ? statement.list :
|
|
965
|
+
statement.kind == "ForEachMapStatement" ? statement.map :
|
|
966
|
+
statement.kind == "LocalDeclaration" ? statement.initializer :
|
|
967
|
+
statement.kind == "AssignmentStatement" ? statement.expression :
|
|
968
|
+
statement.kind == "PrivateFieldWriteStatement" ? statement.expression :
|
|
969
|
+
statement.kind == "ReturnStatement" ? statement.expression :
|
|
970
|
+
statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
|
|
971
|
+
statement.kind == "RaiseStatement" ? statement.error.message : undefined;
|
|
972
|
+
if (capture && expression && (expressionContainsKind(expression, "ListLiteral") ||
|
|
973
|
+
expressionContainsKind(expression, "MapLiteral") || expressionContainsKind(expression, "OrderedMapLiteral") ||
|
|
974
|
+
expressionContainsKind(expression, "OptionalNone") ||
|
|
975
|
+
expressionContainsKind(expression, "OptionalSome"))) {
|
|
976
|
+
unsupportedCapability("java", capture.detail, capture.location);
|
|
977
|
+
}
|
|
978
|
+
if (statement.kind == "IfStatement") {
|
|
979
|
+
validateBlockNames(statement.consequent, capture, owner);
|
|
980
|
+
if (statement.alternate)
|
|
981
|
+
validateBlockNames(statement.alternate, capture, owner);
|
|
982
|
+
}
|
|
983
|
+
if (statement.kind == "WhileStatement")
|
|
984
|
+
validateBlockNames(statement.body, capture, owner);
|
|
985
|
+
if (statement.kind == "ForEachStatement") {
|
|
986
|
+
const loopCapture = statement.valueBinding.name == "java" ? {
|
|
987
|
+
detail: `${owner} iteration binding 'java' captures java.util factory syntax`,
|
|
988
|
+
location: statement.valueBinding.location
|
|
989
|
+
} : capture;
|
|
990
|
+
validateBlockNames(statement.body, loopCapture, owner);
|
|
991
|
+
}
|
|
992
|
+
if (statement.kind == "ForEachMapStatement") {
|
|
993
|
+
const capturedBinding = [statement.keyBinding, statement.valueBinding].find(({ name }) => name == "java");
|
|
994
|
+
const loopCapture = capturedBinding ? {
|
|
995
|
+
detail: `${owner} iteration binding 'java' captures java.util factory syntax`,
|
|
996
|
+
location: capturedBinding.location
|
|
997
|
+
} : capture;
|
|
998
|
+
validateBlockNames(statement.body, loopCapture, owner);
|
|
999
|
+
}
|
|
1000
|
+
if (statement.kind == "TryStatement") {
|
|
1001
|
+
validateBlockNames(statement.body, capture, owner);
|
|
1002
|
+
const catchCapture = statement.catchBinding.name == "java" ? {
|
|
1003
|
+
detail: `${owner} catch binding 'java' captures java.util factory syntax`,
|
|
1004
|
+
location: statement.catchBinding.location
|
|
1005
|
+
} : capture;
|
|
1006
|
+
validateBlockNames(statement.catchBody, catchCapture, owner);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
};
|
|
1010
|
+
validateBlockNames(module.entryPoint.body, undefined, "entry");
|
|
1011
|
+
for (const declaration of module.functions) {
|
|
1012
|
+
const parameter = declaration.parameters.find(({ name }) => name == "java");
|
|
1013
|
+
const capture = parameter ? {
|
|
1014
|
+
detail: "function parameter 'java' captures java.util factory syntax",
|
|
1015
|
+
location: parameter.location
|
|
1016
|
+
} : undefined;
|
|
1017
|
+
validateBlockNames(declaration.body, capture, "function");
|
|
1018
|
+
}
|
|
1019
|
+
for (const declaration of module.classes ?? []) {
|
|
1020
|
+
const callables = [
|
|
1021
|
+
{ body: declaration.constructor.body, owner: /** @type {const} */ ("constructor"), parameters: declaration.constructor.parameters },
|
|
1022
|
+
...declaration.methods.map((method) => ({ body: method.body, owner: /** @type {const} */ ("method"), parameters: method.parameters }))
|
|
1023
|
+
];
|
|
1024
|
+
for (const callable of callables) {
|
|
1025
|
+
const parameter = callable.parameters.find(({ name }) => name == "java");
|
|
1026
|
+
const capture = parameter ? {
|
|
1027
|
+
detail: `${callable.owner} parameter 'java' captures java.util factory syntax`,
|
|
1028
|
+
location: parameter.location
|
|
1029
|
+
} : undefined;
|
|
1030
|
+
validateBlockNames(callable.body, capture, callable.owner);
|
|
1031
|
+
}
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
/**
|
|
1035
|
+
* Reports whether a module contains an expression kind that requires target runtime scaffolding.
|
|
1036
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Validated-shape semantic module.
|
|
1037
|
+
* @param {import("../semantic/types.js").Expression["kind"]} kind - Sought expression kind.
|
|
1038
|
+
* @returns {boolean} Whether the kind occurs.
|
|
1039
|
+
*/
|
|
1040
|
+
function moduleContainsExpressionKind(module, kind) {
|
|
1041
|
+
const classBlocks = (module.classes ?? []).flatMap((declaration) => [
|
|
1042
|
+
declaration.constructor.body, ...declaration.methods.map((method) => method.body)
|
|
1043
|
+
]);
|
|
1044
|
+
return [module.entryPoint.body, ...module.functions.map((declaration) => declaration.body), ...classBlocks].some((block) => allStatements(block).some((statement) => {
|
|
1045
|
+
const expression = statement.kind == "IfStatement" ? statement.condition :
|
|
1046
|
+
statement.kind == "WhileStatement" ? statement.condition :
|
|
1047
|
+
statement.kind == "ForEachStatement" ? statement.list :
|
|
1048
|
+
statement.kind == "ForEachMapStatement" ? statement.map :
|
|
1049
|
+
statement.kind == "LocalDeclaration" ? statement.initializer :
|
|
1050
|
+
statement.kind == "AssignmentStatement" ? statement.expression :
|
|
1051
|
+
statement.kind == "PrivateFieldWriteStatement" ? statement.expression :
|
|
1052
|
+
statement.kind == "ReturnStatement" ? statement.expression :
|
|
1053
|
+
statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement" ? statement.expression :
|
|
1054
|
+
statement.kind == "RaiseStatement" ? statement.error.message : undefined;
|
|
1055
|
+
return expression ? expressionContainsKind(expression, kind) : false;
|
|
1056
|
+
}));
|
|
1057
|
+
}
|
|
1058
|
+
/**
|
|
1059
|
+
* Searches one validated expression tree for a semantic kind.
|
|
1060
|
+
* @param {import("../semantic/types.js").Expression} expression - Expression root.
|
|
1061
|
+
* @param {import("../semantic/types.js").Expression["kind"]} kind - Sought kind.
|
|
1062
|
+
* @returns {boolean} Whether the kind occurs.
|
|
1063
|
+
*/
|
|
1064
|
+
function expressionContainsKind(expression, kind) {
|
|
1065
|
+
if (expression.kind == kind)
|
|
1066
|
+
return true;
|
|
1067
|
+
if (expression.kind == "UnaryExpression")
|
|
1068
|
+
return expressionContainsKind(expression.operand, kind);
|
|
1069
|
+
if (expression.kind == "BinaryExpression") {
|
|
1070
|
+
return expressionContainsKind(expression.left, kind) || expressionContainsKind(expression.right, kind);
|
|
1071
|
+
}
|
|
1072
|
+
if (expression.kind == "CallExpression")
|
|
1073
|
+
return expression.arguments.some((argument) => expressionContainsKind(argument, kind));
|
|
1074
|
+
if (expression.kind == "MethodCallExpression") {
|
|
1075
|
+
return expressionContainsKind(expression.receiver, kind) ||
|
|
1076
|
+
expression.arguments.some((argument) => expressionContainsKind(argument, kind));
|
|
1077
|
+
}
|
|
1078
|
+
if (expression.kind == "RecordConstruction" || expression.kind == "ReferenceConstruction") {
|
|
1079
|
+
return expression.arguments.some((argument) => expressionContainsKind(argument, kind));
|
|
1080
|
+
}
|
|
1081
|
+
if (expression.kind == "MemberRead" || expression.kind == "PrivateFieldRead") {
|
|
1082
|
+
return expressionContainsKind(expression.receiver, kind);
|
|
1083
|
+
}
|
|
1084
|
+
if (expression.kind == "ListLiteral")
|
|
1085
|
+
return expression.elements.some((element) => expressionContainsKind(element, kind));
|
|
1086
|
+
if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral") {
|
|
1087
|
+
return expression.entries.some((entry) => expressionContainsKind(entry.key, kind) || expressionContainsKind(entry.value, kind));
|
|
1088
|
+
}
|
|
1089
|
+
if (expression.kind == "ListIndexExpression") {
|
|
1090
|
+
return expressionContainsKind(expression.collection, kind) || expressionContainsKind(expression.index, kind);
|
|
1091
|
+
}
|
|
1092
|
+
if (expression.kind == "MapLookupExpression") {
|
|
1093
|
+
return expressionContainsKind(expression.collection, kind) || expressionContainsKind(expression.key, kind);
|
|
1094
|
+
}
|
|
1095
|
+
if (expression.kind == "CollectionSizeExpression")
|
|
1096
|
+
return expressionContainsKind(expression.collection, kind);
|
|
1097
|
+
if (expression.kind == "OptionalSome")
|
|
1098
|
+
return expressionContainsKind(expression.value, kind);
|
|
1099
|
+
if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap") {
|
|
1100
|
+
return expressionContainsKind(expression.operand, kind);
|
|
1101
|
+
}
|
|
1102
|
+
return false;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Returns a parser-backed function-name location when one survived semantic adaptation.
|
|
1106
|
+
* @param {import("../semantic/types.js").FunctionDeclaration} declaration - Semantic function declaration.
|
|
1107
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact name or declaration location.
|
|
1108
|
+
*/
|
|
1109
|
+
function declarationNameLocation(declaration) {
|
|
1110
|
+
return declaration.sourceProvenance?.ranges.name ?? declaration.location;
|
|
1111
|
+
}
|
|
1112
|
+
/**
|
|
1113
|
+
* Returns a parser-backed binding-name location when one survived semantic adaptation.
|
|
1114
|
+
* @param {import("../semantic/types.js").Parameter | import("../semantic/types.js").LocalDeclaration | import("../semantic/types.js").ValueBinding | import("../semantic/types.js").CatchBinding} binding - Semantic binding.
|
|
1115
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact name or binding location.
|
|
1116
|
+
*/
|
|
1117
|
+
function bindingNameLocation(binding) {
|
|
1118
|
+
return binding.sourceProvenance?.ranges.name ?? binding.location;
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Builds the Java method signature used for inherited-instance collision checks.
|
|
1122
|
+
* @param {import("../semantic/types.js").FunctionDeclaration} declaration - Candidate Java target function.
|
|
1123
|
+
* @returns {string | undefined} Emitted name and parameter types when all types are supported.
|
|
1124
|
+
*/
|
|
1125
|
+
function emittedJavaFunctionSignature(declaration) {
|
|
1126
|
+
const parameterTypes = [];
|
|
1127
|
+
for (const parameter of declaration.parameters) {
|
|
1128
|
+
const type = parameter.type;
|
|
1129
|
+
if (!type || typeof type != "object" || Array.isArray(type))
|
|
1130
|
+
return undefined;
|
|
1131
|
+
const emitted = type.kind == "ListType" ? "java.util.List" : type.kind == "MapType" ? "java.util.Map" :
|
|
1132
|
+
type.kind == "OrderedMapType" ? "java.util.SequencedMap" :
|
|
1133
|
+
type.kind == "TypeReference" ? emitScalarType("java", type) : undefined;
|
|
1134
|
+
if (!emitted)
|
|
1135
|
+
return undefined;
|
|
1136
|
+
parameterTypes.push(emitted);
|
|
1137
|
+
}
|
|
1138
|
+
return `${declaration.name}(${parameterTypes.join(",")})`;
|
|
1139
|
+
}
|
|
105
1140
|
/**
|
|
106
1141
|
* Returns every statement nested beneath a block in semantic order.
|
|
107
1142
|
* @param {import("../semantic/types.js").Block} block - Semantic block.
|
|
108
1143
|
* @returns {import("../semantic/types.js").Statement[]} Statements including nested branches.
|
|
109
1144
|
*/
|
|
110
1145
|
function allStatements(block) {
|
|
111
|
-
return block.statements.flatMap((statement) =>
|
|
112
|
-
|
|
113
|
-
|
|
1146
|
+
return block.statements.flatMap((statement) => {
|
|
1147
|
+
if (statement.kind == "IfStatement") {
|
|
1148
|
+
return [statement, ...allStatements(statement.consequent), ...(statement.alternate ? allStatements(statement.alternate) : [])];
|
|
1149
|
+
}
|
|
1150
|
+
if (statement.kind == "ForEachStatement" || statement.kind == "ForEachMapStatement") {
|
|
1151
|
+
return [statement, ...allStatements(statement.body)];
|
|
1152
|
+
}
|
|
1153
|
+
if (statement.kind == "WhileStatement")
|
|
1154
|
+
return [statement, ...allStatements(statement.body)];
|
|
1155
|
+
if (statement.kind == "TryStatement")
|
|
1156
|
+
return [statement, ...allStatements(statement.body), ...allStatements(statement.catchBody)];
|
|
1157
|
+
return [statement];
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
/**
|
|
1161
|
+
* Indexes exact loop identities before recursive target validation so cross-function targets fail deterministically.
|
|
1162
|
+
* @param {import("../semantic/types.js").SemanticModule} module - Candidate semantic module.
|
|
1163
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
1164
|
+
* @returns {Map<string, object>} Loop owner by module-local identity.
|
|
1165
|
+
*/
|
|
1166
|
+
function collectLoopOwners(module, language) {
|
|
1167
|
+
const owners = new Map();
|
|
1168
|
+
const classOwners = (module.classes ?? []).flatMap((declaration) => [declaration.constructor, ...declaration.methods]);
|
|
1169
|
+
for (const owner of [...classOwners, ...module.functions, module.entryPoint]) {
|
|
1170
|
+
if (owner && typeof owner == "object" && !Array.isArray(owner))
|
|
1171
|
+
visit(Reflect.get(owner, "body"), owner);
|
|
1172
|
+
}
|
|
1173
|
+
return owners;
|
|
1174
|
+
/**
|
|
1175
|
+
* Visits loop containers while bounding malformed cycles.
|
|
1176
|
+
* @param {unknown} block - Candidate block.
|
|
1177
|
+
* @param {object} owner - Enclosing function or entry point.
|
|
1178
|
+
* @param {Set<object>} [active] - Blocks on the active recursive path.
|
|
1179
|
+
* @returns {void}
|
|
1180
|
+
*/
|
|
1181
|
+
function visit(block, owner, active = new Set()) {
|
|
1182
|
+
if (!block || typeof block != "object" || Array.isArray(block) || active.has(block))
|
|
1183
|
+
return;
|
|
1184
|
+
const statements = Reflect.get(block, "statements");
|
|
1185
|
+
if (!Array.isArray(statements))
|
|
1186
|
+
return;
|
|
1187
|
+
const path = new Set(active);
|
|
1188
|
+
path.add(block);
|
|
1189
|
+
for (const statement of statements) {
|
|
1190
|
+
if (!statement || typeof statement != "object" || Array.isArray(statement))
|
|
1191
|
+
continue;
|
|
1192
|
+
const kind = String(Reflect.get(statement, "kind"));
|
|
1193
|
+
if (["ForEachStatement", "ForEachMapStatement", "WhileStatement"].includes(kind)) {
|
|
1194
|
+
const id = Reflect.get(statement, "id");
|
|
1195
|
+
const location = diagnosticLocation(Reflect.get(statement, "location"), Reflect.get(block, "location"));
|
|
1196
|
+
if (typeof id != "string" || !/^loop:[0-9]+$/u.test(id))
|
|
1197
|
+
continue;
|
|
1198
|
+
if (owners.has(id))
|
|
1199
|
+
unsupportedCapability(language, "duplicate or invalid loop identity", location);
|
|
1200
|
+
owners.set(id, owner);
|
|
1201
|
+
visit(Reflect.get(statement, "body"), owner, path);
|
|
1202
|
+
}
|
|
1203
|
+
else if (kind == "IfStatement") {
|
|
1204
|
+
visit(Reflect.get(statement, "consequent"), owner, path);
|
|
1205
|
+
visit(Reflect.get(statement, "alternate"), owner, path);
|
|
1206
|
+
}
|
|
1207
|
+
else if (kind == "TryStatement") {
|
|
1208
|
+
visit(Reflect.get(statement, "body"), owner, path);
|
|
1209
|
+
visit(Reflect.get(statement, "catchBody"), owner, path);
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
}
|
|
114
1213
|
}
|
|
115
1214
|
/**
|
|
116
1215
|
* Validates one complete semantic block before emission.
|
|
117
1216
|
* @param {unknown} block - Candidate block.
|
|
118
|
-
* @param {import("../semantic/types.js").
|
|
1217
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
119
1218
|
* @param {import("../semantic/types.js").SourceLocation | undefined} ownerLocation - Enclosing location.
|
|
1219
|
+
* @param {{active: (import("../semantic/types.js").ForEachStatement | import("../semantic/types.js").ForEachMapStatement | import("../semantic/types.js").WhileStatement)[], owner: object, owners: Map<string, object>}} loopContext - Active loops and their lexical owner.
|
|
1220
|
+
* @param {Set<object>} [activePath] - Blocks on the active recursive path.
|
|
1221
|
+
* @param {Set<string>} [externalDeclarationIds] - Resolved declarations whose source spelling is target-independent.
|
|
120
1222
|
* @returns {void}
|
|
121
1223
|
*/
|
|
122
|
-
function validateBlock(block, language, ownerLocation) {
|
|
1224
|
+
function validateBlock(block, language, ownerLocation, loopContext, activePath = new Set(), externalDeclarationIds = new Set()) {
|
|
123
1225
|
if (!block || typeof block != "object" || Array.isArray(block)) {
|
|
124
1226
|
return unsupportedCapability(language, "missing or invalid block", ownerLocation);
|
|
125
1227
|
}
|
|
126
1228
|
const candidate = /** @type {import("../semantic/types.js").Block} */ (block);
|
|
127
|
-
const location = candidate.location
|
|
1229
|
+
const location = diagnosticLocation(candidate.location, ownerLocation);
|
|
1230
|
+
if (activePath.has(candidate))
|
|
1231
|
+
unsupportedCapability(language, "cyclic block", location);
|
|
128
1232
|
if (candidate.kind != "Block")
|
|
129
1233
|
unsupportedCapability(language, `block ${String(Reflect.get(block, "kind"))}`, location);
|
|
130
1234
|
if (!Array.isArray(candidate.statements))
|
|
131
1235
|
unsupportedCapability(language, "missing or invalid block statements", location);
|
|
132
|
-
|
|
133
|
-
|
|
1236
|
+
const blockPath = new Set(activePath);
|
|
1237
|
+
blockPath.add(candidate);
|
|
1238
|
+
for (const statement of candidate.statements) {
|
|
1239
|
+
validateStatement(statement, language, location, loopContext, blockPath, externalDeclarationIds);
|
|
1240
|
+
}
|
|
134
1241
|
}
|
|
135
1242
|
/**
|
|
136
1243
|
* Validates one supported statement recursively.
|
|
137
1244
|
* @param {unknown} statement - Candidate statement.
|
|
138
|
-
* @param {import("../semantic/types.js").
|
|
1245
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
139
1246
|
* @param {import("../semantic/types.js").SourceLocation | undefined} ownerLocation - Enclosing body location.
|
|
1247
|
+
* @param {{active: (import("../semantic/types.js").ForEachStatement | import("../semantic/types.js").ForEachMapStatement | import("../semantic/types.js").WhileStatement)[], owner: object, owners: Map<string, object>}} loopContext - Active loops and their lexical owner.
|
|
1248
|
+
* @param {Set<object>} [activePath] - Active block containers.
|
|
1249
|
+
* @param {Set<string>} [externalDeclarationIds] - Resolved declarations whose source spelling is target-independent.
|
|
140
1250
|
* @returns {void}
|
|
141
1251
|
*/
|
|
142
|
-
function validateStatement(statement, language, ownerLocation) {
|
|
1252
|
+
function validateStatement(statement, language, ownerLocation, loopContext, activePath = new Set(), externalDeclarationIds = new Set()) {
|
|
143
1253
|
if (!statement || typeof statement != "object" || Array.isArray(statement)) {
|
|
144
1254
|
return unsupportedCapability(language, "missing or invalid statement", ownerLocation);
|
|
145
1255
|
}
|
|
146
1256
|
const kind = Reflect.get(statement, "kind");
|
|
147
|
-
const
|
|
1257
|
+
const ownLocation = Reflect.get(statement, "location");
|
|
1258
|
+
const location = diagnosticLocation(ownLocation, ownerLocation);
|
|
148
1259
|
if (typeof kind != "string")
|
|
149
1260
|
return unsupportedCapability(language, "missing or invalid statement", location);
|
|
150
1261
|
if (kind == "LocalDeclaration") {
|
|
@@ -153,33 +1264,301 @@ function validateStatement(statement, language, ownerLocation) {
|
|
|
153
1264
|
unsupportedCapability(language, "local declaration with invalid mutability", location);
|
|
154
1265
|
}
|
|
155
1266
|
validateTargetBindingIdentifier(language, declaration.name, "local", location);
|
|
156
|
-
|
|
1267
|
+
if (declaration.type?.kind == "OrderedMapType" && declaration.initializer?.kind != "OrderedMapLiteral") {
|
|
1268
|
+
unsupportedCapability(language, "ordered-map local requires a direct literal initializer", diagnosticLocation(declaration.initializer?.location, location));
|
|
1269
|
+
}
|
|
1270
|
+
if (declaration.initializer?.kind == "OrderedMapLiteral" && declaration.mutable !== false) {
|
|
1271
|
+
unsupportedCapability(language, "ordered-map local must be immutable", location);
|
|
1272
|
+
}
|
|
1273
|
+
validateExpression(declaration.initializer, language, location, false, new Set(), externalDeclarationIds, language == "java" && declaration.initializer?.kind == "OrderedMapLiteral");
|
|
157
1274
|
return;
|
|
158
1275
|
}
|
|
159
1276
|
if (kind == "AssignmentStatement") {
|
|
160
1277
|
const assignment = /** @type {import("../semantic/types.js").AssignmentStatement} */ (statement);
|
|
161
1278
|
validateAssignmentTarget(assignment.target, language, location);
|
|
162
|
-
validateExpression(assignment.expression, language, location);
|
|
1279
|
+
validateExpression(assignment.expression, language, location, false, new Set(), externalDeclarationIds);
|
|
1280
|
+
return;
|
|
1281
|
+
}
|
|
1282
|
+
if (kind == "PrivateFieldWriteStatement") {
|
|
1283
|
+
const assignment = /** @type {import("../semantic/types.js").PrivateFieldWriteStatement} */ (statement);
|
|
1284
|
+
const fields = Object.keys(assignment).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1285
|
+
if (fields != "expression,field,kind,location,receiver" || typeof assignment.field != "string" ||
|
|
1286
|
+
assignment.receiver?.kind != "ReceiverExpression") {
|
|
1287
|
+
unsupportedCapability(language, "malformed private field receiver or private field identity", location);
|
|
1288
|
+
}
|
|
1289
|
+
validateExpression(assignment.receiver, language, location, false, new Set(), externalDeclarationIds);
|
|
1290
|
+
validateExpression(assignment.expression, language, location, false, new Set(), externalDeclarationIds);
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1293
|
+
if (kind == "ReturnStatement") {
|
|
1294
|
+
const expression = Reflect.get(statement, "expression");
|
|
1295
|
+
if (expression !== undefined)
|
|
1296
|
+
validateExpression(expression, language, location, false, new Set(), externalDeclarationIds);
|
|
1297
|
+
if (language == "ruby" && loopContext.active.some(({ kind }) => kind == "ForEachStatement" || kind == "ForEachMapStatement")) {
|
|
1298
|
+
unsupportedCapability(language, "return from an iteration body", location);
|
|
1299
|
+
}
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
if (kind == "ExpressionStatement") {
|
|
1303
|
+
if (!task005Languages.has(language)) {
|
|
1304
|
+
unsupportedCapability(language, "Task 005 void call expression statement", location);
|
|
1305
|
+
}
|
|
1306
|
+
const expression = Reflect.get(statement, "expression");
|
|
1307
|
+
if (!expression || typeof expression != "object" ||
|
|
1308
|
+
!["CallExpression", "EffectCallExpression", "MethodCallExpression"].includes(String(Reflect.get(expression, "kind")))) {
|
|
1309
|
+
unsupportedCapability(language, "expression statement other than a direct or receiver call", location);
|
|
1310
|
+
}
|
|
1311
|
+
validateExpression(expression, language, location, false, new Set(), externalDeclarationIds);
|
|
163
1312
|
return;
|
|
164
1313
|
}
|
|
165
|
-
if (kind == "
|
|
166
|
-
validateExpression(Reflect.get(statement, "expression"), language, location);
|
|
1314
|
+
if (kind == "PrintStatement") {
|
|
1315
|
+
validateExpression(Reflect.get(statement, "expression"), language, location, false, new Set(), externalDeclarationIds);
|
|
167
1316
|
return;
|
|
168
1317
|
}
|
|
169
1318
|
if (kind == "IfStatement") {
|
|
170
1319
|
const branch = /** @type {import("../semantic/types.js").IfStatement} */ (statement);
|
|
171
|
-
validateExpression(branch.condition, language, location);
|
|
172
|
-
validateBlock(branch.consequent, language, location);
|
|
173
|
-
if (Object.hasOwn(branch, "alternate"))
|
|
174
|
-
validateBlock(branch.alternate, language, location);
|
|
1320
|
+
validateExpression(branch.condition, language, location, false, new Set(), externalDeclarationIds);
|
|
1321
|
+
validateBlock(branch.consequent, language, location, loopContext, activePath, externalDeclarationIds);
|
|
1322
|
+
if (Object.hasOwn(branch, "alternate")) {
|
|
1323
|
+
validateBlock(branch.alternate, language, location, loopContext, activePath, externalDeclarationIds);
|
|
1324
|
+
}
|
|
1325
|
+
return;
|
|
1326
|
+
}
|
|
1327
|
+
if (kind == "BreakStatement" || kind == "ContinueStatement") {
|
|
1328
|
+
if (!task008Languages.has(language))
|
|
1329
|
+
unsupportedCapability(language, "Task 008 ordered list iteration", location);
|
|
1330
|
+
requireSemanticLocation(ownLocation, language, `${kind} location`, ownerLocation);
|
|
1331
|
+
const fields = Object.keys(/** @type {object} */ (statement)).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1332
|
+
if (fields != "kind,location,targetLoopId")
|
|
1333
|
+
unsupportedCapability(language, `malformed ${kind}`, location);
|
|
1334
|
+
const targetLoopId = Reflect.get(statement, "targetLoopId");
|
|
1335
|
+
const nearest = loopContext.active.at(-1);
|
|
1336
|
+
if (!nearest)
|
|
1337
|
+
unsupportedCapability(language, `${kind == "BreakStatement" ? "break" : "continue"} outside a loop`, location);
|
|
1338
|
+
if (typeof targetLoopId != "string" || !loopContext.owners.has(targetLoopId)) {
|
|
1339
|
+
unsupportedCapability(language, "invalid loop control target identity", location);
|
|
1340
|
+
}
|
|
1341
|
+
if (loopContext.owners.get(targetLoopId) !== loopContext.owner) {
|
|
1342
|
+
unsupportedCapability(language, "loop control target crosses a function boundary", location);
|
|
1343
|
+
}
|
|
1344
|
+
if (targetLoopId != nearest.id)
|
|
1345
|
+
unsupportedCapability(language, "loop control must target the nearest enclosing loop", location);
|
|
1346
|
+
return;
|
|
1347
|
+
}
|
|
1348
|
+
if (kind == "WhileStatement") {
|
|
1349
|
+
if (!task032Languages.has(language))
|
|
1350
|
+
unsupportedCapability(language, "Task 032 condition-controlled loop", location);
|
|
1351
|
+
const loopLocation = requireSemanticLocation(ownLocation, language, "WhileStatement location", ownerLocation);
|
|
1352
|
+
const loop = /** @type {import("../semantic/types.js").WhileStatement} */ (statement);
|
|
1353
|
+
const fields = Object.keys(loop).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1354
|
+
if (fields != "body,condition,id,kind,location")
|
|
1355
|
+
unsupportedCapability(language, "malformed WhileStatement", loopLocation);
|
|
1356
|
+
if (typeof loop.id != "string" || !/^loop:[0-9]+$/u.test(loop.id) || loopContext.owners.get(loop.id) !== loopContext.owner) {
|
|
1357
|
+
unsupportedCapability(language, "duplicate or invalid loop identity", loopLocation);
|
|
1358
|
+
}
|
|
1359
|
+
if (!loop.condition || typeof loop.condition != "object" || Array.isArray(loop.condition)) {
|
|
1360
|
+
unsupportedCapability(language, "missing or invalid condition-controlled loop condition", loopLocation);
|
|
1361
|
+
}
|
|
1362
|
+
requireSemanticLocation(Reflect.get(loop.condition, "location"), language, "condition-controlled loop condition location", loopLocation);
|
|
1363
|
+
validateExpression(loop.condition, language, loopLocation, false, new Set(), externalDeclarationIds);
|
|
1364
|
+
if (!loop.body || typeof loop.body != "object" || Array.isArray(loop.body)) {
|
|
1365
|
+
unsupportedCapability(language, "missing or invalid condition-controlled loop body", loopLocation);
|
|
1366
|
+
}
|
|
1367
|
+
requireSemanticLocation(Reflect.get(loop.body, "location"), language, "condition-controlled loop body location", loopLocation);
|
|
1368
|
+
validateBlock(loop.body, language, loopLocation, { active: [...loopContext.active, loop], owner: loopContext.owner, owners: loopContext.owners }, activePath, externalDeclarationIds);
|
|
1369
|
+
return;
|
|
1370
|
+
}
|
|
1371
|
+
if (kind == "ForEachStatement") {
|
|
1372
|
+
if (!task008Languages.has(language))
|
|
1373
|
+
unsupportedCapability(language, "Task 008 ordered list iteration", location);
|
|
1374
|
+
const loopLocation = requireSemanticLocation(ownLocation, language, "ForEachStatement location", ownerLocation);
|
|
1375
|
+
const loop = /** @type {import("../semantic/types.js").ForEachStatement} */ (statement);
|
|
1376
|
+
const fields = Object.keys(loop).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1377
|
+
if (fields != "body,id,kind,list,location,valueBinding")
|
|
1378
|
+
unsupportedCapability(language, "malformed ForEachStatement", loopLocation);
|
|
1379
|
+
if (typeof loop.id != "string" || !/^loop:[0-9]+$/u.test(loop.id) || loopContext.owners.get(loop.id) !== loopContext.owner) {
|
|
1380
|
+
unsupportedCapability(language, "duplicate or invalid loop identity", loopLocation);
|
|
1381
|
+
}
|
|
1382
|
+
if (!loop.list || typeof loop.list != "object" || Array.isArray(loop.list)) {
|
|
1383
|
+
unsupportedCapability(language, "missing or invalid iteration collection", loopLocation);
|
|
1384
|
+
}
|
|
1385
|
+
requireSemanticLocation(Reflect.get(loop.list, "location"), language, "iteration collection location", loopLocation);
|
|
1386
|
+
validateExpression(loop.list, language, loopLocation, false, new Set(), externalDeclarationIds);
|
|
1387
|
+
if (!loop.valueBinding || typeof loop.valueBinding != "object" || Array.isArray(loop.valueBinding)) {
|
|
1388
|
+
unsupportedCapability(language, "missing or invalid iteration binding", loopLocation);
|
|
1389
|
+
}
|
|
1390
|
+
const binding = loop.valueBinding;
|
|
1391
|
+
const bindingLocation = requireSemanticLocation(Reflect.get(binding, "location"), language, "iteration binding location", loopLocation);
|
|
1392
|
+
const bindingFields = Object.keys(binding).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1393
|
+
if (binding.kind != "ValueBinding" || bindingFields != "kind,location,mutable,name,type") {
|
|
1394
|
+
unsupportedCapability(language, "malformed iteration binding", bindingLocation);
|
|
1395
|
+
}
|
|
1396
|
+
if (binding.mutable !== false)
|
|
1397
|
+
unsupportedCapability(language, "mutable iteration binding", bindingLocation);
|
|
1398
|
+
validateTargetBindingIdentifier(language, binding.name, "iteration binding", bindingLocation);
|
|
1399
|
+
if (!loop.body || typeof loop.body != "object" || Array.isArray(loop.body)) {
|
|
1400
|
+
unsupportedCapability(language, "missing or invalid iteration body", loopLocation);
|
|
1401
|
+
}
|
|
1402
|
+
requireSemanticLocation(Reflect.get(loop.body, "location"), language, "iteration body location", loopLocation);
|
|
1403
|
+
validateBlock(loop.body, language, loopLocation, { active: [...loopContext.active, loop], owner: loopContext.owner, owners: loopContext.owners }, activePath, externalDeclarationIds);
|
|
1404
|
+
return;
|
|
1405
|
+
}
|
|
1406
|
+
if (kind == "ForEachMapStatement") {
|
|
1407
|
+
if (!task014Languages.has(language))
|
|
1408
|
+
unsupportedCapability(language, "Task 014 ordered-map iteration", location);
|
|
1409
|
+
const loopLocation = requireSemanticLocation(ownLocation, language, "ForEachMapStatement location", ownerLocation);
|
|
1410
|
+
const loop = /** @type {import("../semantic/types.js").ForEachMapStatement} */ (statement);
|
|
1411
|
+
const fields = Object.keys(loop).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1412
|
+
if (fields != "body,id,keyBinding,kind,location,map,valueBinding") {
|
|
1413
|
+
unsupportedCapability(language, "malformed ForEachMapStatement", loopLocation);
|
|
1414
|
+
}
|
|
1415
|
+
if (typeof loop.id != "string" || !/^loop:[0-9]+$/u.test(loop.id) || loopContext.owners.get(loop.id) !== loopContext.owner) {
|
|
1416
|
+
unsupportedCapability(language, "duplicate or invalid loop identity", loopLocation);
|
|
1417
|
+
}
|
|
1418
|
+
if (!loop.map || typeof loop.map != "object" || Array.isArray(loop.map)) {
|
|
1419
|
+
unsupportedCapability(language, "missing or invalid ordered-map iteration collection", loopLocation);
|
|
1420
|
+
}
|
|
1421
|
+
requireSemanticLocation(Reflect.get(loop.map, "location"), language, "ordered-map iteration collection location", loopLocation);
|
|
1422
|
+
validateExpression(loop.map, language, loopLocation, false, new Set(), externalDeclarationIds);
|
|
1423
|
+
for (const [role, binding] of [["key", loop.keyBinding], ["value", loop.valueBinding]]) {
|
|
1424
|
+
if (!binding || typeof binding != "object" || Array.isArray(binding)) {
|
|
1425
|
+
unsupportedCapability(language, `missing or invalid map iteration ${role} binding`, loopLocation);
|
|
1426
|
+
}
|
|
1427
|
+
const bindingLocation = requireSemanticLocation(binding.location, language, `map iteration ${role} binding location`, loopLocation);
|
|
1428
|
+
const bindingFields = Object.keys(binding).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1429
|
+
if (binding.kind != "ValueBinding" || bindingFields != "kind,location,mutable,name,type") {
|
|
1430
|
+
unsupportedCapability(language, `malformed map iteration ${role} binding`, bindingLocation);
|
|
1431
|
+
}
|
|
1432
|
+
if (binding.mutable !== false)
|
|
1433
|
+
unsupportedCapability(language, "Map iteration bindings must be immutable", bindingLocation);
|
|
1434
|
+
validateTargetBindingIdentifier(language, binding.name, `map iteration ${role} binding`, bindingLocation);
|
|
1435
|
+
}
|
|
1436
|
+
if (!loop.body || typeof loop.body != "object" || Array.isArray(loop.body)) {
|
|
1437
|
+
unsupportedCapability(language, "missing or invalid map iteration body", loopLocation);
|
|
1438
|
+
}
|
|
1439
|
+
requireSemanticLocation(Reflect.get(loop.body, "location"), language, "map iteration body location", loopLocation);
|
|
1440
|
+
validateBlock(loop.body, language, loopLocation, { active: [...loopContext.active, loop], owner: loopContext.owner, owners: loopContext.owners }, activePath, externalDeclarationIds);
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
if (kind == "RaiseStatement") {
|
|
1444
|
+
const fields = Object.keys(/** @type {object} */ (statement)).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1445
|
+
const raised = Reflect.get(statement, "error");
|
|
1446
|
+
const raiseLocation = requireSemanticLocation(ownLocation, language, "RaiseStatement location", ownerLocation);
|
|
1447
|
+
const constructionFields = raised && typeof raised == "object" && !Array.isArray(raised)
|
|
1448
|
+
? Object.keys(raised).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
1449
|
+
if (fields != "error,kind,location" || !raised || typeof raised != "object" || Array.isArray(raised) ||
|
|
1450
|
+
raised.kind != "ErrorConstruction" || constructionFields != "error,kind,location,message") {
|
|
1451
|
+
unsupportedCapability(language, "malformed RaiseStatement", raiseLocation);
|
|
1452
|
+
}
|
|
1453
|
+
requireSemanticLocation(raised.location, language, "error construction location", raiseLocation);
|
|
1454
|
+
validateErrorTypeShape(raised.error, language, raised.location);
|
|
1455
|
+
validateExpression(raised.message, language, raised.location, false, new Set(), externalDeclarationIds);
|
|
1456
|
+
return;
|
|
1457
|
+
}
|
|
1458
|
+
if (kind == "TryStatement") {
|
|
1459
|
+
const handler = /** @type {import("../semantic/types.js").TryStatement} */ (statement);
|
|
1460
|
+
const tryLocation = requireSemanticLocation(ownLocation, language, "TryStatement location", ownerLocation);
|
|
1461
|
+
const fields = Object.keys(handler).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1462
|
+
if (fields != "body,catchBinding,catchBody,catchType,kind,location") {
|
|
1463
|
+
unsupportedCapability(language, "malformed TryStatement", tryLocation);
|
|
1464
|
+
}
|
|
1465
|
+
validateErrorTypeShape(handler.catchType, language, tryLocation);
|
|
1466
|
+
const binding = handler.catchBinding;
|
|
1467
|
+
const bindingFields = binding && typeof binding == "object" && !Array.isArray(binding)
|
|
1468
|
+
? Object.keys(binding).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
1469
|
+
const bindingLocation = requireSemanticLocation(binding?.location, language, "catch binding location", tryLocation);
|
|
1470
|
+
if (!binding || binding.kind != "CatchBinding" || bindingFields != "kind,location,mutable,name,type" || binding.mutable !== false) {
|
|
1471
|
+
unsupportedCapability(language, "malformed catch binding", bindingLocation);
|
|
1472
|
+
}
|
|
1473
|
+
validateTargetBindingIdentifier(language, binding.name, "catch binding", bindingLocation);
|
|
1474
|
+
validateErrorTypeShape(binding.type, language, bindingLocation);
|
|
1475
|
+
if (binding.type.declarationId != handler.catchType.declarationId) {
|
|
1476
|
+
unsupportedCapability(language, "catch binding type mismatch", bindingLocation);
|
|
1477
|
+
}
|
|
1478
|
+
validateBlock(handler.body, language, tryLocation, loopContext, activePath, externalDeclarationIds);
|
|
1479
|
+
validateBlock(handler.catchBody, language, tryLocation, loopContext, activePath, externalDeclarationIds);
|
|
175
1480
|
return;
|
|
176
1481
|
}
|
|
177
1482
|
unsupportedCapability(language, `statement ${kind}`, location);
|
|
178
1483
|
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Validates the closed parser-neutral error type shape.
|
|
1486
|
+
* @param {unknown} type - Candidate error type.
|
|
1487
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Target language.
|
|
1488
|
+
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Nearest owning location.
|
|
1489
|
+
* @returns {void}
|
|
1490
|
+
*/
|
|
1491
|
+
function validateErrorTypeShape(/** @type {unknown} */ type,
|
|
1492
|
+
/** @type {import("../semantic/types.js").BackendLanguage} */ language,
|
|
1493
|
+
/** @type {import("../semantic/types.js").SourceLocation} */ ownerLocation) {
|
|
1494
|
+
const fields = type && typeof type == "object" && !Array.isArray(type)
|
|
1495
|
+
? Object.keys(type).filter((key) => key != "sourceProvenance").sort().join(",") : "";
|
|
1496
|
+
const candidate = type && typeof type == "object" && !Array.isArray(type)
|
|
1497
|
+
? /** @type {Record<string, unknown>} */ (type) : {};
|
|
1498
|
+
if (candidate.kind != "ErrorType" || fields != "declarationId,kind" || typeof candidate.declarationId != "string" ||
|
|
1499
|
+
!/^(?:(?:[a-z][a-z0-9._-]*#)?error:[0-9]+|(?:module:[0-9]+\/)?capability:[0-9]+\/failure:[0-9]+)$/u
|
|
1500
|
+
.test(candidate.declarationId)) {
|
|
1501
|
+
unsupportedCapability(language, "missing or invalid error type", ownerLocation);
|
|
1502
|
+
}
|
|
1503
|
+
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Returns a complete semantic location suitable for diagnostic construction.
|
|
1506
|
+
* @param {unknown} candidate - Preferred location.
|
|
1507
|
+
* @param {unknown} fallback - Nearest enclosing location.
|
|
1508
|
+
* @returns {import("../semantic/types.js").SourceLocation | undefined} Safe diagnostic location.
|
|
1509
|
+
*/
|
|
1510
|
+
function diagnosticLocation(candidate, fallback) {
|
|
1511
|
+
if (isSemanticLocation(candidate))
|
|
1512
|
+
return candidate;
|
|
1513
|
+
if (isSemanticLocation(fallback))
|
|
1514
|
+
return fallback;
|
|
1515
|
+
return undefined;
|
|
1516
|
+
}
|
|
1517
|
+
/**
|
|
1518
|
+
* Requires one complete parser-neutral location before any backend or diagnostic consumes it.
|
|
1519
|
+
* @param {unknown} candidate - Required location.
|
|
1520
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend identity.
|
|
1521
|
+
* @param {string} subject - Location owner for a deterministic diagnostic.
|
|
1522
|
+
* @param {unknown} fallback - Nearest enclosing location.
|
|
1523
|
+
* @returns {import("../semantic/types.js").SourceLocation} Validated location.
|
|
1524
|
+
*/
|
|
1525
|
+
function requireSemanticLocation(candidate, language, subject, fallback) {
|
|
1526
|
+
if (!isSemanticLocation(candidate))
|
|
1527
|
+
unsupportedCapability(language, `missing or invalid ${subject}`, diagnosticLocation(fallback, undefined));
|
|
1528
|
+
return candidate;
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Checks a complete ordered UTF-16 source range.
|
|
1532
|
+
* @param {unknown} location - Candidate source range.
|
|
1533
|
+
* @returns {location is import("../semantic/types.js").SourceLocation} Whether the range is safe to consume.
|
|
1534
|
+
*/
|
|
1535
|
+
function isSemanticLocation(location) {
|
|
1536
|
+
if (!location || typeof location != "object" || Array.isArray(location))
|
|
1537
|
+
return false;
|
|
1538
|
+
const candidate = /** @type {{filename?: unknown, start?: unknown, end?: unknown}} */ (location);
|
|
1539
|
+
if (typeof candidate.filename != "string" || candidate.filename.length == 0 ||
|
|
1540
|
+
!isSemanticPoint(candidate.start) || !isSemanticPoint(candidate.end))
|
|
1541
|
+
return false;
|
|
1542
|
+
return candidate.end.offset >= candidate.start.offset && candidate.end.line >= candidate.start.line &&
|
|
1543
|
+
(candidate.end.line != candidate.start.line || candidate.end.column >= candidate.start.column);
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Checks one complete one-based UTF-16 source point.
|
|
1547
|
+
* @param {unknown} point - Candidate source point.
|
|
1548
|
+
* @returns {point is import("../semantic/types.js").SourcePoint} Whether all coordinates are valid.
|
|
1549
|
+
*/
|
|
1550
|
+
function isSemanticPoint(point) {
|
|
1551
|
+
if (!point || typeof point != "object" || Array.isArray(point))
|
|
1552
|
+
return false;
|
|
1553
|
+
const candidate = /** @type {{offset?: unknown, line?: unknown, column?: unknown}} */ (point);
|
|
1554
|
+
return Number.isSafeInteger(candidate.offset) && Number(candidate.offset) >= 0 &&
|
|
1555
|
+
Number.isSafeInteger(candidate.line) && Number(candidate.line) >= 1 &&
|
|
1556
|
+
Number.isSafeInteger(candidate.column) && Number(candidate.column) >= 1;
|
|
1557
|
+
}
|
|
179
1558
|
/**
|
|
180
1559
|
* Validates the simple identifier target introduced by task 002.
|
|
181
1560
|
* @param {unknown} target - Candidate assignment target.
|
|
182
|
-
* @param {import("../semantic/types.js").
|
|
1561
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
183
1562
|
* @param {import("../semantic/types.js").SourceLocation | undefined} ownerLocation - Assignment location.
|
|
184
1563
|
* @returns {void}
|
|
185
1564
|
*/
|
|
@@ -197,17 +1576,24 @@ function validateAssignmentTarget(target, language, ownerLocation) {
|
|
|
197
1576
|
/**
|
|
198
1577
|
* Checks expression backend capabilities recursively.
|
|
199
1578
|
* @param {unknown} expression - Candidate semantic expression.
|
|
200
|
-
* @param {import("../semantic/types.js").
|
|
1579
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
201
1580
|
* @param {import("../semantic/types.js").SourceLocation | undefined} ownerLocation - Nearest owning node location.
|
|
202
1581
|
* @param {boolean} [allowJavaNegatedMinimumOperand] - Whether Java may use 2147483648 only beneath integer negation.
|
|
1582
|
+
* @param {Set<object>} [activePath] - Ancestors on the current recursive validation path.
|
|
1583
|
+
* @param {Set<string>} [externalDeclarationIds] - Resolved declarations whose source spelling is target-independent.
|
|
1584
|
+
* @param {boolean} [allowJavaOrderedMapRoot] - Whether this root is a Java local initializer eligible for statement lowering.
|
|
203
1585
|
* @returns {void}
|
|
204
1586
|
*/
|
|
205
|
-
function validateExpression(expression, language, ownerLocation, allowJavaNegatedMinimumOperand = false) {
|
|
1587
|
+
function validateExpression(expression, language, ownerLocation, allowJavaNegatedMinimumOperand = false, activePath = new Set(), externalDeclarationIds = new Set(), allowJavaOrderedMapRoot = false) {
|
|
206
1588
|
if (!expression || typeof expression != "object" || Array.isArray(expression)) {
|
|
207
1589
|
return unsupportedCapability(language, "missing or invalid expression", ownerLocation);
|
|
208
1590
|
}
|
|
209
1591
|
const candidate = /** @type {import("../semantic/types.js").Expression} */ (expression);
|
|
210
1592
|
const location = candidate.location ?? ownerLocation;
|
|
1593
|
+
if (activePath.has(candidate))
|
|
1594
|
+
unsupportedCapability(language, "cyclic expression", location);
|
|
1595
|
+
const expressionPath = new Set(activePath);
|
|
1596
|
+
expressionPath.add(candidate);
|
|
211
1597
|
if (typeof candidate.kind != "string") {
|
|
212
1598
|
return unsupportedCapability(language, "missing or invalid expression", location);
|
|
213
1599
|
}
|
|
@@ -215,6 +1601,31 @@ function validateExpression(expression, language, ownerLocation, allowJavaNegate
|
|
|
215
1601
|
validateTargetIdentifier(language, candidate.name, "reference", location);
|
|
216
1602
|
return;
|
|
217
1603
|
}
|
|
1604
|
+
if (candidate.kind == "ReceiverExpression") {
|
|
1605
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1606
|
+
if (fields != "classId,kind,location" || typeof candidate.classId != "string" ||
|
|
1607
|
+
!/^(?:[a-z][a-z0-9._-]*#)?class:[0-9]+$/u.test(candidate.classId)) {
|
|
1608
|
+
unsupportedCapability(language, "malformed private field receiver", location);
|
|
1609
|
+
}
|
|
1610
|
+
return;
|
|
1611
|
+
}
|
|
1612
|
+
if (candidate.kind == "ErrorMessageRead") {
|
|
1613
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1614
|
+
if (fields != "kind,location,receiver" || candidate.receiver?.kind != "IdentifierExpression") {
|
|
1615
|
+
unsupportedCapability(language, "malformed ErrorMessageRead", location);
|
|
1616
|
+
}
|
|
1617
|
+
validateExpression(candidate.receiver, language, location, false, expressionPath, externalDeclarationIds);
|
|
1618
|
+
return;
|
|
1619
|
+
}
|
|
1620
|
+
if (candidate.kind == "OwnedMoveExpression" || candidate.kind == "OwnedBorrowExpression") {
|
|
1621
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1622
|
+
const expected = candidate.kind == "OwnedMoveExpression" ? "expression,kind,location,type" : "expression,kind,location,mode,type";
|
|
1623
|
+
if (fields != expected || candidate.expression.kind != "IdentifierExpression" && candidate.expression.kind != "ReceiverExpression" &&
|
|
1624
|
+
candidate.expression.kind != "PrivateFieldRead")
|
|
1625
|
+
unsupportedCapability(language, `malformed ${candidate.kind}`, location);
|
|
1626
|
+
validateExpression(candidate.expression, language, location, false, expressionPath, externalDeclarationIds);
|
|
1627
|
+
return;
|
|
1628
|
+
}
|
|
218
1629
|
if (candidate.kind == "IntegerLiteral") {
|
|
219
1630
|
if (!Number.isSafeInteger(candidate.value)) {
|
|
220
1631
|
unsupportedCapability(language, "non-safe integer literal", location);
|
|
@@ -223,31 +1634,198 @@ function validateExpression(expression, language, ownerLocation, allowJavaNegate
|
|
|
223
1634
|
if (language == "java" && !validNegatedMinimumOperand && (candidate.value < -2147483648 || candidate.value > 2147483647)) {
|
|
224
1635
|
unsupportedCapability(language, "integer literal outside signed 32-bit int range", location);
|
|
225
1636
|
}
|
|
226
|
-
if ((language == "csharp" || language == "go" || language == "c" || language == "cpp") && candidate.value < 0 ||
|
|
227
|
-
(language == "c" || language == "cpp") && Object.is(candidate.value, -0)) {
|
|
1637
|
+
if ((language == "csharp" || language == "go" || language == "c" || language == "cpp" || language == "dart" || language == "kotlin" || language == "rust" || language == "swift") && candidate.value < 0 ||
|
|
1638
|
+
(language == "c" || language == "cpp" || language == "dart" || language == "kotlin" || language == "rust" || language == "swift") && Object.is(candidate.value, -0)) {
|
|
228
1639
|
unsupportedCapability(language, "negative integer literal without semantic negation", location);
|
|
229
1640
|
}
|
|
230
1641
|
return;
|
|
231
1642
|
}
|
|
232
1643
|
if (candidate.kind == "BooleanLiteral" || candidate.kind == "StringLiteral")
|
|
233
1644
|
return;
|
|
1645
|
+
if (["OptionalNone", "OptionalSome", "OptionalIsPresent", "OptionalUnwrap"].includes(candidate.kind)) {
|
|
1646
|
+
if (!task007Languages.has(language))
|
|
1647
|
+
unsupportedCapability(language, "Task 007 optional values", location);
|
|
1648
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1649
|
+
const expectedFields = candidate.kind == "OptionalNone" ? "kind,location" :
|
|
1650
|
+
candidate.kind == "OptionalSome" ? "kind,location,value" : "kind,location,operand";
|
|
1651
|
+
if (fields != expectedFields)
|
|
1652
|
+
unsupportedCapability(language, `malformed ${candidate.kind}`, location);
|
|
1653
|
+
if (candidate.kind == "OptionalNone")
|
|
1654
|
+
return;
|
|
1655
|
+
if (candidate.kind == "OptionalSome") {
|
|
1656
|
+
validateExpression(candidate.value, language, location, false, expressionPath, externalDeclarationIds);
|
|
1657
|
+
return;
|
|
1658
|
+
}
|
|
1659
|
+
const operation = /** @type {import("../semantic/types.js").OptionalIsPresent | import("../semantic/types.js").OptionalUnwrap} */ (candidate);
|
|
1660
|
+
if (!operation.operand || operation.operand.kind != "IdentifierExpression") {
|
|
1661
|
+
unsupportedCapability(language, `${candidate.kind} without a simple identifier operand`, location);
|
|
1662
|
+
}
|
|
1663
|
+
validateExpression(operation.operand, language, location, false, expressionPath, externalDeclarationIds);
|
|
1664
|
+
return;
|
|
1665
|
+
}
|
|
1666
|
+
if (["ListLiteral", "MapLiteral", "OrderedMapLiteral", "ListIndexExpression", "MapLookupExpression", "CollectionSizeExpression"].includes(candidate.kind)) {
|
|
1667
|
+
if (!task006Languages.has(language))
|
|
1668
|
+
unsupportedCapability(language, "Task 006 immutable collections", location);
|
|
1669
|
+
if (candidate.kind == "OrderedMapLiteral" && !task014Languages.has(language)) {
|
|
1670
|
+
unsupportedCapability(language, "Task 014 ordered-map iteration", location);
|
|
1671
|
+
}
|
|
1672
|
+
if (candidate.kind == "OrderedMapLiteral" && language == "java" && !allowJavaOrderedMapRoot) {
|
|
1673
|
+
unsupportedCapability(language, "unsafe Java ordered-map expression lowering", location);
|
|
1674
|
+
}
|
|
1675
|
+
if (candidate.kind == "ListLiteral") {
|
|
1676
|
+
if (!isDenseArray(candidate.elements))
|
|
1677
|
+
unsupportedCapability(language, "missing or sparse list elements", location);
|
|
1678
|
+
for (const element of candidate.elements) {
|
|
1679
|
+
validateExpression(element, language, location, false, expressionPath, externalDeclarationIds);
|
|
1680
|
+
}
|
|
1681
|
+
return;
|
|
1682
|
+
}
|
|
1683
|
+
if (candidate.kind == "MapLiteral" || candidate.kind == "OrderedMapLiteral") {
|
|
1684
|
+
if (!isDenseArray(candidate.entries))
|
|
1685
|
+
unsupportedCapability(language, "missing or sparse map entries", location);
|
|
1686
|
+
if (candidate.kind == "MapLiteral" && language == "java" && candidate.entries.length > 10) {
|
|
1687
|
+
unsupportedCapability(language, "java.util.Map.of supports at most ten entries", location);
|
|
1688
|
+
}
|
|
1689
|
+
for (const entry of candidate.entries) {
|
|
1690
|
+
if (!entry || entry.kind != "MapEntry" || !entry.key || entry.key.kind != "StringLiteral") {
|
|
1691
|
+
unsupportedCapability(language, "missing or invalid map entry", entry?.location ?? location);
|
|
1692
|
+
}
|
|
1693
|
+
validateExpression(entry.key, language, entry.location, false, expressionPath, externalDeclarationIds);
|
|
1694
|
+
validateExpression(entry.value, language, entry.location, false, expressionPath, externalDeclarationIds);
|
|
1695
|
+
}
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
if (candidate.kind == "ListIndexExpression") {
|
|
1699
|
+
if (candidate.totality == "fail-on-absence" && language != "java") {
|
|
1700
|
+
unsupportedCapability(language, "list access depends on Java-specific bounds failure", location);
|
|
1701
|
+
}
|
|
1702
|
+
validateExpression(candidate.collection, language, location, false, expressionPath, externalDeclarationIds);
|
|
1703
|
+
validateExpression(candidate.index, language, location, false, expressionPath, externalDeclarationIds);
|
|
1704
|
+
return;
|
|
1705
|
+
}
|
|
1706
|
+
if (candidate.kind == "MapLookupExpression") {
|
|
1707
|
+
if (candidate.totality == "fail-on-absence" && language != "ruby") {
|
|
1708
|
+
unsupportedCapability(language, "map lookup depends on Ruby fetch absence failure", location);
|
|
1709
|
+
}
|
|
1710
|
+
validateExpression(candidate.collection, language, location, false, expressionPath, externalDeclarationIds);
|
|
1711
|
+
validateExpression(candidate.key, language, location, false, expressionPath, externalDeclarationIds);
|
|
1712
|
+
return;
|
|
1713
|
+
}
|
|
1714
|
+
if (candidate.kind == "CollectionSizeExpression") {
|
|
1715
|
+
if (candidate.collectionKind != "list" && candidate.collectionKind != "map") {
|
|
1716
|
+
unsupportedCapability(language, "collection size without a validated receiver kind", location);
|
|
1717
|
+
}
|
|
1718
|
+
validateExpression(candidate.collection, language, location, false, expressionPath, externalDeclarationIds);
|
|
1719
|
+
return;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
234
1722
|
if (candidate.kind == "CallExpression") {
|
|
235
|
-
|
|
1723
|
+
const declarationId = candidate.resolution && typeof candidate.resolution == "object" && !Array.isArray(candidate.resolution)
|
|
1724
|
+
? Reflect.get(candidate.resolution, "declarationId")
|
|
1725
|
+
: undefined;
|
|
1726
|
+
if (typeof declarationId != "string" || !externalDeclarationIds.has(declarationId)) {
|
|
1727
|
+
validateTargetIdentifier(language, candidate.callee, "callee", location);
|
|
1728
|
+
}
|
|
1729
|
+
if (!candidate.resolution || typeof candidate.resolution != "object" || Array.isArray(candidate.resolution)) {
|
|
1730
|
+
unsupportedCapability(language, "missing or invalid resolved call signature", location);
|
|
1731
|
+
}
|
|
236
1732
|
if (!Array.isArray(candidate.arguments)) {
|
|
237
1733
|
unsupportedCapability(language, "missing or invalid call arguments", location);
|
|
238
1734
|
}
|
|
239
|
-
if (candidate.arguments.length != 2) {
|
|
1735
|
+
if (!task005Languages.has(language) && candidate.arguments.length != 2) {
|
|
240
1736
|
unsupportedCapability(language, "call argument count other than two", location);
|
|
241
1737
|
}
|
|
1738
|
+
for (const argument of candidate.arguments) {
|
|
1739
|
+
validateExpression(argument, language, location, false, expressionPath, externalDeclarationIds);
|
|
1740
|
+
}
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
if (candidate.kind == "EffectCallExpression") {
|
|
1744
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1745
|
+
const resolution = candidate.resolution;
|
|
1746
|
+
if (fields != "arguments,effectSiteId,kind,location,operation,resolution" || !isDenseArray(candidate.arguments) ||
|
|
1747
|
+
typeof candidate.effectSiteId != "string" || typeof candidate.operation != "string" || !resolution ||
|
|
1748
|
+
resolution.kind != "ResolvedEffectOperationSignature" || resolution.operationId != candidate.operation ||
|
|
1749
|
+
!isDenseArray(resolution.parameterTypes) || !isDenseArray(resolution.failureIds) || resolution.effects?.join(",") != "host") {
|
|
1750
|
+
unsupportedCapability(language, "malformed authorized effect call", location);
|
|
1751
|
+
}
|
|
242
1752
|
for (const argument of candidate.arguments)
|
|
243
|
-
validateExpression(argument, language, location);
|
|
1753
|
+
validateExpression(argument, language, location, false, expressionPath, externalDeclarationIds);
|
|
1754
|
+
return;
|
|
1755
|
+
}
|
|
1756
|
+
if (candidate.kind == "ReferenceConstruction") {
|
|
1757
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1758
|
+
const resolution = candidate.resolution;
|
|
1759
|
+
const effectfulFields = "arguments,effectSiteId,effects,failureIds,kind,location,reference,resolution";
|
|
1760
|
+
const pureFields = "arguments,kind,location,reference,resolution";
|
|
1761
|
+
if (![pureFields, effectfulFields].includes(fields) ||
|
|
1762
|
+
candidate.reference?.kind != "ReferenceType" && candidate.reference?.kind != "OwnedReferenceType" ||
|
|
1763
|
+
typeof candidate.reference.declarationId != "string" || !isDenseArray(candidate.arguments) ||
|
|
1764
|
+
!resolution || resolution.kind != "ResolvedConstructorSignature" ||
|
|
1765
|
+
resolution.declarationId != `${candidate.reference.declarationId}:constructor` || !isDenseArray(resolution.parameterTypes) ||
|
|
1766
|
+
fields == effectfulFields &&
|
|
1767
|
+
(typeof candidate.effectSiteId != "string" || candidate.effects?.join(",") != "host" || !isDenseArray(candidate.failureIds))) {
|
|
1768
|
+
unsupportedCapability(language, "malformed reference construction or resolved constructor signature", location);
|
|
1769
|
+
}
|
|
1770
|
+
for (const argument of candidate.arguments) {
|
|
1771
|
+
validateExpression(argument, language, location, false, expressionPath, externalDeclarationIds);
|
|
1772
|
+
}
|
|
1773
|
+
return;
|
|
1774
|
+
}
|
|
1775
|
+
if (candidate.kind == "MethodCallExpression") {
|
|
1776
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1777
|
+
const resolution = candidate.resolution;
|
|
1778
|
+
const effectfulFields = "arguments,effectSiteId,effects,failureIds,kind,location,method,receiver,resolution";
|
|
1779
|
+
const pureFields = "arguments,kind,location,method,receiver,resolution";
|
|
1780
|
+
if (![pureFields, effectfulFields].includes(fields) || typeof candidate.method != "string" ||
|
|
1781
|
+
!isDenseArray(candidate.arguments) || !resolution || resolution.kind != "ResolvedMethodSignature" ||
|
|
1782
|
+
resolution.declarationId != candidate.method || !isDenseArray(resolution.parameterTypes) ||
|
|
1783
|
+
!Object.hasOwn(resolution, "returnType") || Object.hasOwn(resolution, "resourceFlow") &&
|
|
1784
|
+
(!resolution.resourceFlow || !["preserve", "terminal"].includes(String(resolution.resourceFlow.kind)) ||
|
|
1785
|
+
Object.hasOwn(resolution.resourceFlow, "terminalFailureId") && typeof resolution.resourceFlow.terminalFailureId != "string") ||
|
|
1786
|
+
fields == effectfulFields &&
|
|
1787
|
+
(typeof candidate.effectSiteId != "string" || candidate.effects?.join(",") != "host" || !isDenseArray(candidate.failureIds))) {
|
|
1788
|
+
unsupportedCapability(language, "malformed receiver call or resolved method signature", location);
|
|
1789
|
+
}
|
|
1790
|
+
validateExpression(candidate.receiver, language, location, false, expressionPath, externalDeclarationIds);
|
|
1791
|
+
for (const argument of candidate.arguments) {
|
|
1792
|
+
validateExpression(argument, language, location, false, expressionPath, externalDeclarationIds);
|
|
1793
|
+
}
|
|
1794
|
+
return;
|
|
1795
|
+
}
|
|
1796
|
+
if (candidate.kind == "RecordConstruction") {
|
|
1797
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1798
|
+
if (fields != "arguments,kind,location,record" || !candidate.record || candidate.record.kind != "RecordType" ||
|
|
1799
|
+
typeof candidate.record.declarationId != "string" || !isDenseArray(candidate.arguments)) {
|
|
1800
|
+
unsupportedCapability(language, "malformed RecordConstruction", location);
|
|
1801
|
+
}
|
|
1802
|
+
for (const argument of candidate.arguments) {
|
|
1803
|
+
validateExpression(argument, language, location, false, expressionPath, externalDeclarationIds);
|
|
1804
|
+
}
|
|
1805
|
+
return;
|
|
1806
|
+
}
|
|
1807
|
+
if (candidate.kind == "MemberRead") {
|
|
1808
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1809
|
+
if (fields != "field,kind,location,receiver" || typeof candidate.field != "string") {
|
|
1810
|
+
unsupportedCapability(language, "malformed MemberRead", location);
|
|
1811
|
+
}
|
|
1812
|
+
validateExpression(candidate.receiver, language, location, false, expressionPath, externalDeclarationIds);
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
if (candidate.kind == "PrivateFieldRead") {
|
|
1816
|
+
const fields = Object.keys(candidate).filter((key) => key != "sourceProvenance").sort().join(",");
|
|
1817
|
+
if (fields != "field,kind,location,receiver" || typeof candidate.field != "string" ||
|
|
1818
|
+
candidate.receiver?.kind != "ReceiverExpression") {
|
|
1819
|
+
unsupportedCapability(language, "malformed private field receiver or private field identity", location);
|
|
1820
|
+
}
|
|
1821
|
+
validateExpression(candidate.receiver, language, location, false, expressionPath, externalDeclarationIds);
|
|
244
1822
|
return;
|
|
245
1823
|
}
|
|
246
1824
|
if (candidate.kind == "UnaryExpression") {
|
|
247
1825
|
if (!Object.hasOwn(unaryOperationSyntax, String(candidate.operation))) {
|
|
248
1826
|
unsupportedCapability(language, `unary operation ${String(candidate.operation)}`, location);
|
|
249
1827
|
}
|
|
250
|
-
validateExpression(candidate.operand, language, location, candidate.operation == "IntegerNegate");
|
|
1828
|
+
validateExpression(candidate.operand, language, location, candidate.operation == "IntegerNegate", expressionPath, externalDeclarationIds);
|
|
251
1829
|
validateKnownTargetInteger(candidate, language, location);
|
|
252
1830
|
return;
|
|
253
1831
|
}
|
|
@@ -255,8 +1833,8 @@ function validateExpression(expression, language, ownerLocation, allowJavaNegate
|
|
|
255
1833
|
if (!Object.hasOwn(binaryOperationSyntax, String(candidate.operation))) {
|
|
256
1834
|
unsupportedCapability(language, `binary operation ${String(candidate.operation)}`, location);
|
|
257
1835
|
}
|
|
258
|
-
validateExpression(candidate.left, language, location);
|
|
259
|
-
validateExpression(candidate.right, language, location);
|
|
1836
|
+
validateExpression(candidate.left, language, location, false, expressionPath, externalDeclarationIds);
|
|
1837
|
+
validateExpression(candidate.right, language, location, false, expressionPath, externalDeclarationIds);
|
|
260
1838
|
validateKnownTargetInteger(candidate, language, location);
|
|
261
1839
|
return;
|
|
262
1840
|
}
|
|
@@ -265,7 +1843,7 @@ function validateExpression(expression, language, ownerLocation, allowJavaNegate
|
|
|
265
1843
|
/**
|
|
266
1844
|
* Rejects compile-time-known Java integer operation results outside primitive int.
|
|
267
1845
|
* @param {import("../semantic/types.js").UnaryExpression | import("../semantic/types.js").BinaryExpression} expression - Validated operation shape.
|
|
268
|
-
* @param {import("../semantic/types.js").
|
|
1846
|
+
* @param {import("../semantic/types.js").BackendLanguage} language - Backend language or binary target.
|
|
269
1847
|
* @param {import("../semantic/types.js").SourceLocation | undefined} location - Operation location.
|
|
270
1848
|
* @returns {void}
|
|
271
1849
|
*/
|
|
@@ -274,9 +1852,14 @@ function validateKnownTargetInteger(expression, language, location) {
|
|
|
274
1852
|
if (language == "java" && value !== undefined && (value < -2147483648n || value > 2147483647n)) {
|
|
275
1853
|
unsupportedCapability(language, "compile-time-known integer operation outside signed 32-bit int range", location);
|
|
276
1854
|
}
|
|
277
|
-
if ((language == "csharp" || language == "go" || language == "c" || language == "cpp") && value !== undefined &&
|
|
1855
|
+
if ((language == "csharp" || language == "go" || language == "c" || language == "cpp" || language == "rust" || language == "swift" || language == "wasm") && value !== undefined &&
|
|
278
1856
|
(value < -9223372036854775808n || value > 9223372036854775807n)) {
|
|
279
|
-
|
|
1857
|
+
const scalar = language == "wasm" ? "i64" : language == "swift" ? "Int64" : "long";
|
|
1858
|
+
unsupportedCapability(language, `compile-time-known integer operation outside signed 64-bit ${scalar} range`, location);
|
|
1859
|
+
}
|
|
1860
|
+
if ((language == "dart" || language == "kotlin") && value !== undefined &&
|
|
1861
|
+
(value < -BigInt(Number.MAX_SAFE_INTEGER) || value > BigInt(Number.MAX_SAFE_INTEGER))) {
|
|
1862
|
+
unsupportedCapability(language, "compile-time-known integer operation outside the Semantifold safe-integer range", location);
|
|
280
1863
|
}
|
|
281
1864
|
}
|
|
282
1865
|
/**
|
|
@@ -305,46 +1888,384 @@ function knownIntegerValue(expression) {
|
|
|
305
1888
|
return left * right;
|
|
306
1889
|
return undefined;
|
|
307
1890
|
}
|
|
1891
|
+
/**
|
|
1892
|
+
* Emits one recursive semantic type while mapping every constituent identity.
|
|
1893
|
+
* @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
|
|
1894
|
+
* @param {import("../semantic/types.js").SemanticFunctionReturnType} type - Semantic type.
|
|
1895
|
+
* @param {string} path - Exact type occurrence path.
|
|
1896
|
+
* @param {import("../semantic/types.js").TextBackendLanguage} language - Target language.
|
|
1897
|
+
* @param {boolean} [javaBoxed] - Whether a Java scalar is a generic argument.
|
|
1898
|
+
* @returns {void}
|
|
1899
|
+
*/
|
|
1900
|
+
export function emitType(writer, type, path, language, javaBoxed = false) {
|
|
1901
|
+
if (type.kind == "TypeVariableReference") {
|
|
1902
|
+
const parameter = writer.typeParameterForId(type.parameterId);
|
|
1903
|
+
writer.mapped(parameter.name, { mappingKind: "exact", name: parameter.name, node: type, path, role: "type" });
|
|
1904
|
+
return;
|
|
1905
|
+
}
|
|
1906
|
+
if (type.kind == "RecordType") {
|
|
1907
|
+
const record = writer.recordForId(type.declarationId);
|
|
1908
|
+
writer.mapped(writer.recordNameForId(type.declarationId), {
|
|
1909
|
+
mappingKind: "exact", name: record.name, node: type, path, role: "type"
|
|
1910
|
+
});
|
|
1911
|
+
if (type.arguments) {
|
|
1912
|
+
writer.mapped(language == "ruby" ? "[" : "<", { mappingKind: "anchor", node: type, path });
|
|
1913
|
+
type.arguments.forEach((argument, index) => {
|
|
1914
|
+
if (index > 0)
|
|
1915
|
+
writer.synthetic(language == "php" || language == "ruby" || language == "java" ? "," : ", ", "generic type argument separator", [type], [path]);
|
|
1916
|
+
emitType(writer, argument, `${path}/arguments/${index}`, language, language == "java");
|
|
1917
|
+
});
|
|
1918
|
+
writer.mapped(language == "ruby" ? "]" : ">", { mappingKind: "anchor", node: type, path });
|
|
1919
|
+
}
|
|
1920
|
+
return;
|
|
1921
|
+
}
|
|
1922
|
+
if (type.kind == "ReferenceType") {
|
|
1923
|
+
const declaration = writer.classForId(type.declarationId);
|
|
1924
|
+
writer.mapped(writer.classNameForId(type.declarationId), {
|
|
1925
|
+
mappingKind: "exact", name: declaration.name, node: type, path, role: "type"
|
|
1926
|
+
});
|
|
1927
|
+
return;
|
|
1928
|
+
}
|
|
1929
|
+
if (type.kind == "OwnedResourceType") {
|
|
1930
|
+
const resource = writer.resourceForId(type.resourceId);
|
|
1931
|
+
writer.mapped(writer.capabilityNominalName(resource.name), { mappingKind: "exact", name: resource.name, node: type, path, role: "type" });
|
|
1932
|
+
return;
|
|
1933
|
+
}
|
|
1934
|
+
if (type.kind == "OwnedReferenceType") {
|
|
1935
|
+
const declaration = writer.classForId(type.declarationId);
|
|
1936
|
+
writer.mapped(writer.classNameForId(type.declarationId), { mappingKind: "exact", name: declaration.name, node: type, path, role: "type" });
|
|
1937
|
+
return;
|
|
1938
|
+
}
|
|
1939
|
+
if (type.kind == "TypeReference") {
|
|
1940
|
+
const spelling = language == "java" && javaBoxed
|
|
1941
|
+
? type.name == "integer" ? "Integer" : type.name == "boolean" ? "Boolean" : type.name == "string" ? "String" : "void"
|
|
1942
|
+
: emitScalarType(language, type);
|
|
1943
|
+
writer.mapped(spelling, { mappingKind: "exact", node: type, path, role: "type" });
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
if (type.kind == "OptionalType") {
|
|
1947
|
+
const prefix = language == "java" ? "java.util.Optional<" : language == "php" ? "?" : "";
|
|
1948
|
+
writer.mapped(prefix, { mappingKind: "exact", node: type, path, role: "type" });
|
|
1949
|
+
emitType(writer, type.valueType, `${path}/valueType`, language, language == "java");
|
|
1950
|
+
writer.mapped(language == "java" ? ">" : language == "ruby" ? "?" : language == "javascript" ? "|null" :
|
|
1951
|
+
language == "typescript" ? " | null" : "", { mappingKind: "anchor", node: type, path });
|
|
1952
|
+
return;
|
|
1953
|
+
}
|
|
1954
|
+
const prefix = type.kind == "ListType"
|
|
1955
|
+
? language == "ruby" ? "Array[" : language == "php" ? "list<" :
|
|
1956
|
+
language == "java" ? "java.util.List<" : "ReadonlyArray<"
|
|
1957
|
+
: language == "ruby" ? "Hash[" : language == "php" ? "array<" :
|
|
1958
|
+
language == "java" ? type.kind == "OrderedMapType" ? "java.util.SequencedMap<" : "java.util.Map<" : "ReadonlyMap<";
|
|
1959
|
+
writer.mapped(prefix, { mappingKind: "exact", node: type, path, role: "type" });
|
|
1960
|
+
if (type.kind == "ListType") {
|
|
1961
|
+
emitType(writer, type.elementType, `${path}/elementType`, language, language == "java");
|
|
1962
|
+
}
|
|
1963
|
+
else {
|
|
1964
|
+
emitType(writer, type.keyType, `${path}/keyType`, language, language == "java");
|
|
1965
|
+
writer.synthetic(language == "javascript" || language == "typescript" ? ", " : ",", "map type separator", [type], [path]);
|
|
1966
|
+
emitType(writer, type.valueType, `${path}/valueType`, language, language == "java");
|
|
1967
|
+
}
|
|
1968
|
+
writer.mapped(language == "ruby" ? "]" : ">", { mappingKind: "anchor", node: type, path });
|
|
1969
|
+
}
|
|
308
1970
|
/**
|
|
309
1971
|
* Emits a supported expression.
|
|
310
1972
|
* @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
|
|
311
1973
|
* @param {import("../semantic/types.js").Expression} expression - Semantic expression.
|
|
312
1974
|
* @param {string} path - Exact JSON Pointer for this expression occurrence.
|
|
313
|
-
* @param {import("../semantic/types.js").
|
|
1975
|
+
* @param {import("../semantic/types.js").TextBackendLanguage} language - Target language.
|
|
314
1976
|
* @param {(name: string) => string} emitIdentifier - Identifier formatter.
|
|
315
1977
|
* @returns {void}
|
|
316
1978
|
*/
|
|
317
1979
|
export function emitExpression(writer, expression, path, language, emitIdentifier) {
|
|
1980
|
+
const effectTemporary = writer.effectReplacementName(expression);
|
|
1981
|
+
if (effectTemporary) {
|
|
1982
|
+
writer.synthetic(emitIdentifier(effectTemporary), "exactly-once effect temporary read", [expression], [path]);
|
|
1983
|
+
return;
|
|
1984
|
+
}
|
|
318
1985
|
if (expression.kind == "IdentifierExpression") {
|
|
319
1986
|
writer.mapped(emitIdentifier(expression.name), { mappingKind: "exact", node: expression, path, role: "name" });
|
|
320
1987
|
return;
|
|
321
1988
|
}
|
|
1989
|
+
if (expression.kind == "ReceiverExpression") {
|
|
1990
|
+
writer.mapped(language == "php" ? "$this" : language == "ruby" ? "self" : "this", { mappingKind: "exact", node: expression, path, role: "receiver" });
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
if (expression.kind == "OwnedMoveExpression" || expression.kind == "OwnedBorrowExpression") {
|
|
1994
|
+
if (expression.expression.kind == "IdentifierExpression") {
|
|
1995
|
+
writer.mapped(emitIdentifier(expression.expression.name), { mappingKind: "exact", name: expression.expression.name,
|
|
1996
|
+
node: expression, path, role: "name" });
|
|
1997
|
+
}
|
|
1998
|
+
else if (expression.expression.kind == "ReceiverExpression") {
|
|
1999
|
+
writer.mapped(language == "php" ? "$this" : language == "ruby" ? "self" : "this", { mappingKind: "exact", node: expression, path, role: "receiver" });
|
|
2000
|
+
}
|
|
2001
|
+
else {
|
|
2002
|
+
const field = writer.privateFieldForId(expression.expression.field);
|
|
2003
|
+
if (language != "ruby") {
|
|
2004
|
+
emitExpression(writer, expression.expression.receiver, `${path}/expression/receiver`, language, emitIdentifier);
|
|
2005
|
+
}
|
|
2006
|
+
writer.mapped(language == "php" ? `->${field.name}` : language == "javascript" ? `.#${field.name}` :
|
|
2007
|
+
language == "ruby" ? `@${field.name}` : `.${field.name}`, { mappingKind: "exact", name: field.name, node: expression, path, role: "member" });
|
|
2008
|
+
}
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
322
2011
|
if (expression.kind == "IntegerLiteral") {
|
|
323
|
-
const spelling = language == "csharp" ? `${expression.value}L` : String(expression.value);
|
|
2012
|
+
const spelling = language == "csharp" || language == "kotlin" ? `${expression.value}L` : String(expression.value);
|
|
324
2013
|
writer.mapped(spelling, { mappingKind: "exact", node: expression, path, role: "literal" });
|
|
325
2014
|
return;
|
|
326
2015
|
}
|
|
327
2016
|
if (expression.kind == "BooleanLiteral") {
|
|
328
2017
|
const spelling = language == "python" ? expression.value ? "True" : "False" : expression.value ? "true" : "false";
|
|
2018
|
+
if (language == "dart") {
|
|
2019
|
+
writer.synthetic("_semantifoldBoolean(", "Dart analyzed Boolean literal", [expression], [path]);
|
|
2020
|
+
}
|
|
329
2021
|
writer.mapped(spelling, { mappingKind: "exact", node: expression, path, role: "literal" });
|
|
2022
|
+
if (language == "dart")
|
|
2023
|
+
writer.synthetic(")", "Dart analyzed Boolean literal", [expression], [path]);
|
|
330
2024
|
return;
|
|
331
2025
|
}
|
|
332
2026
|
if (expression.kind == "StringLiteral") {
|
|
333
2027
|
writer.mapped(emitStringLiteral(language, expression.value), { mappingKind: "exact", node: expression, path, role: "literal" });
|
|
334
2028
|
return;
|
|
335
2029
|
}
|
|
2030
|
+
if (expression.kind == "OptionalNone") {
|
|
2031
|
+
writer.mapped(language == "java" ? "java.util.Optional.empty()" : language == "ruby" ? "nil" : "null", {
|
|
2032
|
+
mappingKind: "exact", node: expression, path, role: "absence"
|
|
2033
|
+
});
|
|
2034
|
+
return;
|
|
2035
|
+
}
|
|
2036
|
+
if (expression.kind == "OptionalSome") {
|
|
2037
|
+
if (language == "java") {
|
|
2038
|
+
writer.mapped("java.util.Optional.of(", { mappingKind: "exact", node: expression, path, role: "some" });
|
|
2039
|
+
}
|
|
2040
|
+
else {
|
|
2041
|
+
writer.mapped("(", { mappingKind: "exact", node: expression, path, role: "some" });
|
|
2042
|
+
}
|
|
2043
|
+
emitExpression(writer, expression.value, `${path}/value`, language, emitIdentifier);
|
|
2044
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
if (expression.kind == "OptionalIsPresent") {
|
|
2048
|
+
if (language == "ruby")
|
|
2049
|
+
writer.mapped("!", { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
2050
|
+
else if (language != "java")
|
|
2051
|
+
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
2052
|
+
emitExpression(writer, expression.operand, `${path}/operand`, language, emitIdentifier);
|
|
2053
|
+
writer.mapped(language == "java" ? ".isPresent()" : language == "ruby" ? ".nil?" : " !== null", {
|
|
2054
|
+
mappingKind: "exact", node: expression, path, role: "operator"
|
|
2055
|
+
});
|
|
2056
|
+
if (language != "ruby" && language != "java")
|
|
2057
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2058
|
+
return;
|
|
2059
|
+
}
|
|
2060
|
+
if (expression.kind == "OptionalUnwrap") {
|
|
2061
|
+
if (language != "java") {
|
|
2062
|
+
writer.mapped("(", { mappingKind: "exact", node: expression, path, role: "unwrap" });
|
|
2063
|
+
}
|
|
2064
|
+
emitExpression(writer, expression.operand, `${path}/operand`, language, emitIdentifier);
|
|
2065
|
+
if (language == "java") {
|
|
2066
|
+
writer.mapped(".get()", { mappingKind: "exact", node: expression, path, role: "unwrap" });
|
|
2067
|
+
}
|
|
2068
|
+
else
|
|
2069
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2070
|
+
return;
|
|
2071
|
+
}
|
|
2072
|
+
if (expression.kind == "ListLiteral") {
|
|
2073
|
+
writer.mapped(language == "java" ? "java.util.List.of(" : "[", { mappingKind: "anchor", node: expression, path });
|
|
2074
|
+
expression.elements.forEach((element, index) => {
|
|
2075
|
+
if (index)
|
|
2076
|
+
writer.synthetic(", ", "list element separator", [expression], [path]);
|
|
2077
|
+
emitExpression(writer, element, `${path}/elements/${index}`, language, emitIdentifier);
|
|
2078
|
+
});
|
|
2079
|
+
writer.mapped(language == "java" ? ")" : "]", { mappingKind: "anchor", node: expression, path });
|
|
2080
|
+
return;
|
|
2081
|
+
}
|
|
2082
|
+
if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral") {
|
|
2083
|
+
const open = language == "java" ? "java.util.Map.of(" : language == "javascript" || language == "typescript" ? "new Map([" :
|
|
2084
|
+
language == "php" ? "[" : "{";
|
|
2085
|
+
const close = language == "java" ? ")" : language == "javascript" || language == "typescript" ? "])" :
|
|
2086
|
+
language == "php" ? "]" : "}";
|
|
2087
|
+
writer.mapped(open, { mappingKind: "anchor", node: expression, path });
|
|
2088
|
+
expression.entries.forEach((entry, index) => {
|
|
2089
|
+
const entryPath = `${path}/entries/${index}`;
|
|
2090
|
+
if (index)
|
|
2091
|
+
writer.synthetic(", ", "map entry separator", [expression], [path]);
|
|
2092
|
+
if (language == "javascript" || language == "typescript")
|
|
2093
|
+
writer.mapped("[", { mappingKind: "anchor", node: entry, path: entryPath });
|
|
2094
|
+
emitExpression(writer, entry.key, `${entryPath}/key`, language, emitIdentifier);
|
|
2095
|
+
writer.mapped(language == "ruby" ? " => " : language == "php" ? " => " : ", ", {
|
|
2096
|
+
mappingKind: "exact", node: entry, path: entryPath, role: "operator"
|
|
2097
|
+
});
|
|
2098
|
+
emitExpression(writer, entry.value, `${entryPath}/value`, language, emitIdentifier);
|
|
2099
|
+
if (language == "javascript" || language == "typescript")
|
|
2100
|
+
writer.mapped("]", { mappingKind: "anchor", node: entry, path: entryPath });
|
|
2101
|
+
});
|
|
2102
|
+
writer.mapped(close, { mappingKind: "anchor", node: expression, path });
|
|
2103
|
+
return;
|
|
2104
|
+
}
|
|
2105
|
+
if (expression.kind == "ListIndexExpression") {
|
|
2106
|
+
emitExpression(writer, expression.collection, `${path}/collection`, language, emitIdentifier);
|
|
2107
|
+
writer.mapped(language == "java" ? ".get(" : "[", { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
2108
|
+
emitExpression(writer, expression.index, `${path}/index`, language, emitIdentifier);
|
|
2109
|
+
writer.mapped(language == "java" ? ")" : "]", { mappingKind: "anchor", node: expression, path });
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
if (expression.kind == "MapLookupExpression") {
|
|
2113
|
+
emitExpression(writer, expression.collection, `${path}/collection`, language, emitIdentifier);
|
|
2114
|
+
const operator = language == "ruby" ? ".fetch(" : language == "php" ? "[" : ".get(";
|
|
2115
|
+
writer.mapped(operator, { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
2116
|
+
emitExpression(writer, expression.key, `${path}/key`, language, emitIdentifier);
|
|
2117
|
+
writer.mapped(language == "php" ? "]" : ")", { mappingKind: "anchor", node: expression, path });
|
|
2118
|
+
if (language == "typescript") {
|
|
2119
|
+
writer.synthetic("!", "statically proven map lookup", [expression], [path]);
|
|
2120
|
+
}
|
|
2121
|
+
return;
|
|
2122
|
+
}
|
|
2123
|
+
if (expression.kind == "CollectionSizeExpression") {
|
|
2124
|
+
if (language == "php") {
|
|
2125
|
+
writer.mapped("count(", { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
2126
|
+
emitExpression(writer, expression.collection, `${path}/collection`, language, emitIdentifier);
|
|
2127
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2128
|
+
return;
|
|
2129
|
+
}
|
|
2130
|
+
emitExpression(writer, expression.collection, `${path}/collection`, language, emitIdentifier);
|
|
2131
|
+
const operator = language == "ruby" || language == "java" ? ".size" :
|
|
2132
|
+
expression.collectionKind == "list" ? ".length" : ".size";
|
|
2133
|
+
writer.mapped(`${operator}${language == "java" ? "()" : ""}`, {
|
|
2134
|
+
mappingKind: "exact", node: expression, path, role: "operator"
|
|
2135
|
+
});
|
|
2136
|
+
return;
|
|
2137
|
+
}
|
|
336
2138
|
if (expression.kind == "CallExpression") {
|
|
337
|
-
|
|
2139
|
+
const dartMultiline = language == "dart" && expression.arguments.length > 0 &&
|
|
2140
|
+
dartExpressionExceedsPageWidth(writer, expression);
|
|
2141
|
+
const dartIndent = dartMultiline ? currentLineIndent(writer) : "";
|
|
2142
|
+
writer.mapped(writer.callNameFor(expression), {
|
|
2143
|
+
mappingKind: "exact", name: expression.callee, node: expression, path, role: "callee"
|
|
2144
|
+
});
|
|
338
2145
|
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
339
2146
|
expression.arguments.forEach((argument, index) => {
|
|
340
|
-
if (
|
|
2147
|
+
if (dartMultiline)
|
|
2148
|
+
writer.synthetic(`${index ? "" : "\n"}${dartIndent} `, "Dart argument indentation", [expression], [path]);
|
|
2149
|
+
else if (index > 0)
|
|
341
2150
|
writer.synthetic(", ", "argument separator", [expression], [path]);
|
|
342
2151
|
emitExpression(writer, argument, `${path}/arguments/${index}`, language, emitIdentifier);
|
|
2152
|
+
if (dartMultiline)
|
|
2153
|
+
writer.synthetic(",\n", "Dart formatter argument separator", [expression], [path]);
|
|
2154
|
+
});
|
|
2155
|
+
if (dartMultiline)
|
|
2156
|
+
writer.synthetic(dartIndent, "Dart call closing indentation", [expression], [path]);
|
|
2157
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2158
|
+
return;
|
|
2159
|
+
}
|
|
2160
|
+
if (expression.kind == "EffectCallExpression") {
|
|
2161
|
+
const operation = writer.effectOperationForId(expression.operation);
|
|
2162
|
+
if (language == "java" && writer.referenceClassEmissionDepth > 0) {
|
|
2163
|
+
writer.synthetic("Main.", "protected Task 034 host support owner", [expression], [path]);
|
|
2164
|
+
}
|
|
2165
|
+
writer.mapped(writer.stdlibProviderEntryFor(operation) ?? operation.name, {
|
|
2166
|
+
mappingKind: "exact", name: operation.name, node: expression, path, role: "callee"
|
|
2167
|
+
});
|
|
2168
|
+
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
2169
|
+
expression.arguments.forEach((argument, index) => {
|
|
2170
|
+
if (index > 0)
|
|
2171
|
+
writer.synthetic(", ", "effect argument separator", [expression], [path]);
|
|
2172
|
+
emitExpression(writer, argument, `${path}/arguments/${index}`, language, emitIdentifier);
|
|
2173
|
+
});
|
|
2174
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2175
|
+
return;
|
|
2176
|
+
}
|
|
2177
|
+
if (expression.kind == "ReferenceConstruction") {
|
|
2178
|
+
const declaration = writer.classForId(expression.reference.declarationId);
|
|
2179
|
+
const name = writer.classNameForId(expression.reference.declarationId);
|
|
2180
|
+
const prefix = language == "ruby" ? `${name}.new` : `new ${name}`;
|
|
2181
|
+
writer.mapped(prefix, { mappingKind: "exact", name: declaration.name, node: expression, path, role: "class" });
|
|
2182
|
+
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
2183
|
+
expression.arguments.forEach((argument, index) => {
|
|
2184
|
+
if (index > 0)
|
|
2185
|
+
writer.synthetic(", ", "constructor argument separator", [expression], [path]);
|
|
2186
|
+
emitExpression(writer, argument, `${path}/arguments/${index}`, language, emitIdentifier);
|
|
2187
|
+
});
|
|
2188
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2189
|
+
return;
|
|
2190
|
+
}
|
|
2191
|
+
if (expression.kind == "MethodCallExpression") {
|
|
2192
|
+
emitExpression(writer, expression.receiver, `${path}/receiver`, language, emitIdentifier);
|
|
2193
|
+
const method = writer.methodForId(expression.method);
|
|
2194
|
+
writer.mapped(`${language == "php" ? "->" : "."}${method.name}`, {
|
|
2195
|
+
mappingKind: "exact", name: method.name, node: expression, path, role: "member"
|
|
2196
|
+
});
|
|
2197
|
+
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
2198
|
+
expression.arguments.forEach((argument, index) => {
|
|
2199
|
+
if (index > 0)
|
|
2200
|
+
writer.synthetic(", ", "method argument separator", [expression], [path]);
|
|
2201
|
+
emitExpression(writer, argument, `${path}/arguments/${index}`, language, emitIdentifier);
|
|
2202
|
+
});
|
|
2203
|
+
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
2204
|
+
return;
|
|
2205
|
+
}
|
|
2206
|
+
if (expression.kind == "RecordConstruction") {
|
|
2207
|
+
const record = writer.recordForId(expression.record.declarationId);
|
|
2208
|
+
const targetName = writer.recordNameForId(expression.record.declarationId, true);
|
|
2209
|
+
const prefix = language == "ruby" ? `${targetName}.new` : `new ${targetName}`;
|
|
2210
|
+
writer.mapped(prefix, { mappingKind: "exact", name: record.name, node: expression, path, role: "record" });
|
|
2211
|
+
if ((language == "typescript" || language == "java") && expression.record.arguments) {
|
|
2212
|
+
writer.mapped("<", { mappingKind: "anchor", node: expression.record, path: `${path}/record` });
|
|
2213
|
+
expression.record.arguments.forEach((argument, index) => {
|
|
2214
|
+
if (index > 0)
|
|
2215
|
+
writer.synthetic(language == "java" ? "," : ", ", "generic construction argument separator", [expression.record], [`${path}/record`]);
|
|
2216
|
+
emitType(writer, argument, `${path}/record/arguments/${index}`, language, language == "java");
|
|
2217
|
+
});
|
|
2218
|
+
writer.mapped(">", { mappingKind: "anchor", node: expression.record, path: `${path}/record` });
|
|
2219
|
+
}
|
|
2220
|
+
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
2221
|
+
expression.arguments.forEach((argument, index) => {
|
|
2222
|
+
if (index > 0)
|
|
2223
|
+
writer.synthetic(", ", "record argument separator", [expression], [path]);
|
|
2224
|
+
emitExpression(writer, argument, `${path}/arguments/${index}`, language, emitIdentifier);
|
|
343
2225
|
});
|
|
344
2226
|
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
345
2227
|
return;
|
|
346
2228
|
}
|
|
2229
|
+
if (expression.kind == "MemberRead") {
|
|
2230
|
+
emitExpression(writer, expression.receiver, `${path}/receiver`, language, emitIdentifier);
|
|
2231
|
+
const field = writer.fieldForId(expression.field);
|
|
2232
|
+
const phpGenericRecord = language == "php" &&
|
|
2233
|
+
(writer.recordForFieldId(expression.field).typeParameters?.length ?? 0) > 0;
|
|
2234
|
+
const spelling = language == "php" ? `->${field.name}${phpGenericRecord ? "()" : ""}` :
|
|
2235
|
+
language == "java" ? `.${field.name}()` : `.${field.name}`;
|
|
2236
|
+
writer.mapped(spelling, { mappingKind: "exact", node: expression, path, role: "member" });
|
|
2237
|
+
return;
|
|
2238
|
+
}
|
|
2239
|
+
if (expression.kind == "PrivateFieldRead") {
|
|
2240
|
+
const field = writer.privateFieldForId(expression.field);
|
|
2241
|
+
if (language == "ruby") {
|
|
2242
|
+
writer.mapped(`@${field.name}`, { mappingKind: "exact", name: field.name, node: expression, path, role: "member" });
|
|
2243
|
+
return;
|
|
2244
|
+
}
|
|
2245
|
+
emitExpression(writer, expression.receiver, `${path}/receiver`, language, emitIdentifier);
|
|
2246
|
+
writer.mapped(language == "php" ? `->${field.name}` : language == "javascript" ? `.#${field.name}` : `.${field.name}`, { mappingKind: "exact", name: field.name, node: expression, path, role: "member" });
|
|
2247
|
+
return;
|
|
2248
|
+
}
|
|
2249
|
+
if (expression.kind == "ErrorMessageRead") {
|
|
2250
|
+
emitExpression(writer, expression.receiver, `${path}/receiver`, language, emitIdentifier);
|
|
2251
|
+
writer.mapped(language == "php" ? "->getMessage()" : language == "java" ? ".getMessage()" : ".message", {
|
|
2252
|
+
mappingKind: "exact", node: expression, path, role: "member"
|
|
2253
|
+
});
|
|
2254
|
+
return;
|
|
2255
|
+
}
|
|
347
2256
|
if (expression.kind == "UnaryExpression") {
|
|
2257
|
+
if (language == "dart" && expression.operation == "IntegerNegate") {
|
|
2258
|
+
emitDartIntegerHelper(writer, expression, path, "_semantifoldIntegerNegate", [
|
|
2259
|
+
[expression.operand, `${path}/operand`]
|
|
2260
|
+
]);
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
if (language == "kotlin" && expression.operation == "IntegerNegate") {
|
|
2264
|
+
emitKotlinIntegerHelper(writer, expression, path, "semantifold_integer_negate", [
|
|
2265
|
+
[expression.operand, `${path}/operand`]
|
|
2266
|
+
]);
|
|
2267
|
+
return;
|
|
2268
|
+
}
|
|
348
2269
|
if (language == "csharp" && expression.operation == "IntegerNegate") {
|
|
349
2270
|
writer.mapped("checked(", { mappingKind: "anchor", node: expression, path });
|
|
350
2271
|
writer.mapped("-", { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
@@ -360,6 +2281,22 @@ export function emitExpression(writer, expression, path, language, emitIdentifie
|
|
|
360
2281
|
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
361
2282
|
return;
|
|
362
2283
|
}
|
|
2284
|
+
if (language == "dart" && ["IntegerAdd", "IntegerSubtract", "IntegerMultiply"].includes(expression.operation)) {
|
|
2285
|
+
const helper = expression.operation == "IntegerAdd" ? "_semantifoldIntegerAdd" :
|
|
2286
|
+
expression.operation == "IntegerSubtract" ? "_semantifoldIntegerSubtract" : "_semantifoldIntegerMultiply";
|
|
2287
|
+
emitDartIntegerHelper(writer, expression, path, helper, [
|
|
2288
|
+
[expression.left, `${path}/left`], [expression.right, `${path}/right`]
|
|
2289
|
+
]);
|
|
2290
|
+
return;
|
|
2291
|
+
}
|
|
2292
|
+
if (language == "kotlin" && ["IntegerAdd", "IntegerSubtract", "IntegerMultiply"].includes(expression.operation)) {
|
|
2293
|
+
const helper = expression.operation == "IntegerAdd" ? "semantifold_integer_add" :
|
|
2294
|
+
expression.operation == "IntegerSubtract" ? "semantifold_integer_subtract" : "semantifold_integer_multiply";
|
|
2295
|
+
emitKotlinIntegerHelper(writer, expression, path, helper, [
|
|
2296
|
+
[expression.left, `${path}/left`], [expression.right, `${path}/right`]
|
|
2297
|
+
]);
|
|
2298
|
+
return;
|
|
2299
|
+
}
|
|
363
2300
|
if (language == "csharp" && ["IntegerAdd", "IntegerSubtract", "IntegerMultiply"].includes(expression.operation)) {
|
|
364
2301
|
writer.mapped("checked(", { mappingKind: "anchor", node: expression, path });
|
|
365
2302
|
emitExpression(writer, expression.left, `${path}/left`, language, emitIdentifier);
|
|
@@ -390,6 +2327,19 @@ export function emitExpression(writer, expression, path, language, emitIdentifie
|
|
|
390
2327
|
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
391
2328
|
return;
|
|
392
2329
|
}
|
|
2330
|
+
if (language == "swift" && (expression.operation == "StringEqual" || expression.operation == "StringNotEqual")) {
|
|
2331
|
+
writer.mapped(expression.operation == "StringEqual" ? "semantifold_string_equal" : "semantifold_string_not_equal", {
|
|
2332
|
+
mappingKind: "exact", node: expression, path, role: "operator"
|
|
2333
|
+
});
|
|
2334
|
+
writer.synthetic("(", "Swift scalar-equality helper call", [expression], [path]);
|
|
2335
|
+
emitExpression(writer, expression.left, `${path}/left`, language, emitIdentifier);
|
|
2336
|
+
writer.synthetic(", ", "Swift scalar-equality argument separator", [expression], [path]);
|
|
2337
|
+
emitExpression(writer, expression.right, `${path}/right`, language, emitIdentifier);
|
|
2338
|
+
writer.synthetic(")", "Swift scalar-equality helper call", [expression], [path]);
|
|
2339
|
+
return;
|
|
2340
|
+
}
|
|
2341
|
+
const dartMultiline = language == "dart" && dartExpressionExceedsPageWidth(writer, expression);
|
|
2342
|
+
const dartIndent = dartMultiline ? currentLineIndent(writer) : "";
|
|
393
2343
|
writer.mapped("(", { mappingKind: "anchor", node: expression, path });
|
|
394
2344
|
emitExpression(writer, expression.left, `${path}/left`, language, emitIdentifier);
|
|
395
2345
|
writer.synthetic(" ", "operator spacing", [expression], [path]);
|
|
@@ -400,10 +2350,115 @@ export function emitExpression(writer, expression, path, language, emitIdentifie
|
|
|
400
2350
|
}
|
|
401
2351
|
else
|
|
402
2352
|
writer.mapped(spelling, { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
403
|
-
writer.synthetic(" ", "operator spacing", [expression], [path]);
|
|
2353
|
+
writer.synthetic(dartMultiline ? `\n${dartIndent} ` : " ", "operator spacing", [expression], [path]);
|
|
404
2354
|
emitExpression(writer, expression.right, `${path}/right`, language, emitIdentifier);
|
|
405
2355
|
writer.mapped(")", { mappingKind: "anchor", node: expression, path });
|
|
406
2356
|
}
|
|
2357
|
+
/**
|
|
2358
|
+
* Emits a Kotlin checked-integer helper while preserving the semantic operator range.
|
|
2359
|
+
* @param {import("./writer.js").SourceWriter} writer - Source-aware writer.
|
|
2360
|
+
* @param {import("../semantic/types.js").UnaryExpression | import("../semantic/types.js").BinaryExpression} expression - Operation.
|
|
2361
|
+
* @param {string} path - Operation path.
|
|
2362
|
+
* @param {string} helper - Exact target helper.
|
|
2363
|
+
* @param {[import("../semantic/types.js").Expression, string][]} operands - Ordered operands and paths.
|
|
2364
|
+
*/
|
|
2365
|
+
function emitKotlinIntegerHelper(writer, expression, path, helper, operands) {
|
|
2366
|
+
writer.mapped(helper, { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
2367
|
+
writer.synthetic("(", "Kotlin checked-integer helper call", [expression], [path]);
|
|
2368
|
+
operands.forEach(([operand, operandPath], index) => {
|
|
2369
|
+
if (index)
|
|
2370
|
+
writer.synthetic(", ", "Kotlin checked-integer argument separator", [expression], [path]);
|
|
2371
|
+
emitExpression(writer, operand, operandPath, "kotlin", identityIdentifier);
|
|
2372
|
+
});
|
|
2373
|
+
writer.synthetic(")", "Kotlin checked-integer helper call", [expression], [path]);
|
|
2374
|
+
}
|
|
2375
|
+
/**
|
|
2376
|
+
* Emits a compiler-owned Dart checked-integer helper call.
|
|
2377
|
+
* @param {import("./writer.js").SourceWriter} writer Source-aware writer.
|
|
2378
|
+
* @param {import("../semantic/types.js").UnaryExpression | import("../semantic/types.js").BinaryExpression} expression Operation.
|
|
2379
|
+
* @param {string} path Operation path.
|
|
2380
|
+
* @param {string} helper Exact target helper.
|
|
2381
|
+
* @param {[import("../semantic/types.js").Expression, string][]} operands Ordered operands and paths.
|
|
2382
|
+
* @returns {void}
|
|
2383
|
+
*/
|
|
2384
|
+
function emitDartIntegerHelper(writer, expression, path, helper, operands) {
|
|
2385
|
+
const flatLength = helper.length + 2 + operands.reduce((total, [operand], index) => total + flatDartExpression(writer, operand).length + (index ? 2 : 0), 0);
|
|
2386
|
+
const multiline = writer.column - 1 + flatLength > 80;
|
|
2387
|
+
const indent = multiline ? currentLineIndent(writer) : "";
|
|
2388
|
+
writer.mapped(helper, { mappingKind: "exact", node: expression, path, role: "operator" });
|
|
2389
|
+
writer.synthetic("(", "Dart checked-integer helper call", [expression], [path]);
|
|
2390
|
+
operands.forEach(([operand, operandPath], index) => {
|
|
2391
|
+
if (multiline)
|
|
2392
|
+
writer.synthetic(`${index ? "" : "\n"}${indent} `, "Dart checked-integer argument indentation", [expression], [path]);
|
|
2393
|
+
else if (index)
|
|
2394
|
+
writer.synthetic(", ", "Dart checked-integer argument separator", [expression], [path]);
|
|
2395
|
+
emitExpression(writer, operand, operandPath, "dart", identityIdentifier);
|
|
2396
|
+
if (multiline)
|
|
2397
|
+
writer.synthetic(",\n", "Dart formatter checked-integer argument separator", [expression], [path]);
|
|
2398
|
+
});
|
|
2399
|
+
if (multiline)
|
|
2400
|
+
writer.synthetic(indent, "Dart checked-integer closing indentation", [expression], [path]);
|
|
2401
|
+
writer.synthetic(")", "Dart checked-integer helper call", [expression], [path]);
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* Reports whether Dart's default 80-column formatter must split an expression at the current site.
|
|
2405
|
+
* @param {import("./writer.js").SourceWriter} writer Source-aware writer.
|
|
2406
|
+
* @param {import("../semantic/types.js").Expression} expression Semantic expression.
|
|
2407
|
+
* @returns {boolean} Whether the flat expression crosses the formatter boundary.
|
|
2408
|
+
*/
|
|
2409
|
+
function dartExpressionExceedsPageWidth(writer, expression) {
|
|
2410
|
+
return writer.column - 1 + flatDartExpression(writer, expression).length > 80;
|
|
2411
|
+
}
|
|
2412
|
+
/**
|
|
2413
|
+
* Returns the current generated line's structural indentation.
|
|
2414
|
+
* @param {import("./writer.js").SourceWriter} writer Source-aware writer.
|
|
2415
|
+
* @returns {string} Leading spaces.
|
|
2416
|
+
*/
|
|
2417
|
+
function currentLineIndent(writer) {
|
|
2418
|
+
return /^ */u.exec(writer.code.slice(writer.code.lastIndexOf("\n") + 1))?.[0] ?? "";
|
|
2419
|
+
}
|
|
2420
|
+
/**
|
|
2421
|
+
* Renders the bounded Task-005 Dart expression profile without mappings for page-width planning.
|
|
2422
|
+
* @param {import("./writer.js").SourceWriter} writer Source-aware writer.
|
|
2423
|
+
* @param {import("../semantic/types.js").Expression} expression Semantic expression.
|
|
2424
|
+
* @returns {string} Flat canonical spelling.
|
|
2425
|
+
*/
|
|
2426
|
+
function flatDartExpression(writer, expression) {
|
|
2427
|
+
if (expression.kind == "IdentifierExpression")
|
|
2428
|
+
return expression.name;
|
|
2429
|
+
if (expression.kind == "IntegerLiteral")
|
|
2430
|
+
return String(expression.value);
|
|
2431
|
+
if (expression.kind == "BooleanLiteral")
|
|
2432
|
+
return `_semantifoldBoolean(${expression.value ? "true" : "false"})`;
|
|
2433
|
+
if (expression.kind == "StringLiteral")
|
|
2434
|
+
return emitStringLiteral("dart", expression.value);
|
|
2435
|
+
if (expression.kind == "CallExpression") {
|
|
2436
|
+
return `${writer.callNameFor(expression)}(${expression.arguments.map((argument) => flatDartExpression(writer, argument)).join(", ")})`;
|
|
2437
|
+
}
|
|
2438
|
+
if (expression.kind == "UnaryExpression") {
|
|
2439
|
+
const operand = flatDartExpression(writer, expression.operand);
|
|
2440
|
+
return expression.operation == "IntegerNegate" ? `_semantifoldIntegerNegate(${operand})` : `(!${operand})`;
|
|
2441
|
+
}
|
|
2442
|
+
if (expression.kind == "BinaryExpression") {
|
|
2443
|
+
const left = flatDartExpression(writer, expression.left);
|
|
2444
|
+
const right = flatDartExpression(writer, expression.right);
|
|
2445
|
+
if (["IntegerAdd", "IntegerSubtract", "IntegerMultiply"].includes(expression.operation)) {
|
|
2446
|
+
const helper = expression.operation == "IntegerAdd" ? "_semantifoldIntegerAdd" :
|
|
2447
|
+
expression.operation == "IntegerSubtract" ? "_semantifoldIntegerSubtract" : "_semantifoldIntegerMultiply";
|
|
2448
|
+
return `${helper}(${left}, ${right})`;
|
|
2449
|
+
}
|
|
2450
|
+
return `(${left} ${binaryOperationSpelling(expression.operation, "dart")} ${right})`;
|
|
2451
|
+
}
|
|
2452
|
+
throw new TypeError("Unsupported Dart expression reached formatter planning after preflight.");
|
|
2453
|
+
}
|
|
2454
|
+
/**
|
|
2455
|
+
* Preserves a Kotlin identifier spelling.
|
|
2456
|
+
* @param {string} name - Identifier spelling.
|
|
2457
|
+
* @returns {string} Unchanged spelling.
|
|
2458
|
+
*/
|
|
2459
|
+
function identityIdentifier(name) {
|
|
2460
|
+
return name;
|
|
2461
|
+
}
|
|
407
2462
|
/**
|
|
408
2463
|
* Reports whether JavaScript-family execution can create IEEE-754 signed zero.
|
|
409
2464
|
* Semantifold integers have one mathematical zero, so those targets canonicalize
|
|
@@ -427,11 +2482,28 @@ function blockContainsSignProducingOperation(block) {
|
|
|
427
2482
|
blockContainsSignProducingOperation(statement.consequent) ||
|
|
428
2483
|
Boolean(statement.alternate && blockContainsSignProducingOperation(statement.alternate));
|
|
429
2484
|
}
|
|
2485
|
+
if (statement.kind == "ForEachStatement") {
|
|
2486
|
+
return expressionContainsSignProducingOperation(statement.list) || blockContainsSignProducingOperation(statement.body);
|
|
2487
|
+
}
|
|
2488
|
+
if (statement.kind == "ForEachMapStatement") {
|
|
2489
|
+
return expressionContainsSignProducingOperation(statement.map) || blockContainsSignProducingOperation(statement.body);
|
|
2490
|
+
}
|
|
2491
|
+
if (statement.kind == "WhileStatement") {
|
|
2492
|
+
return expressionContainsSignProducingOperation(statement.condition) || blockContainsSignProducingOperation(statement.body);
|
|
2493
|
+
}
|
|
2494
|
+
if (statement.kind == "TryStatement") {
|
|
2495
|
+
return blockContainsSignProducingOperation(statement.body) || blockContainsSignProducingOperation(statement.catchBody);
|
|
2496
|
+
}
|
|
2497
|
+
if (statement.kind == "RaiseStatement")
|
|
2498
|
+
return expressionContainsSignProducingOperation(statement.error.message);
|
|
430
2499
|
if (statement.kind == "LocalDeclaration")
|
|
431
2500
|
return expressionContainsSignProducingOperation(statement.initializer);
|
|
432
|
-
if (statement.kind == "AssignmentStatement" || statement.kind == "
|
|
2501
|
+
if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
|
|
433
2502
|
return expressionContainsSignProducingOperation(statement.expression);
|
|
434
2503
|
}
|
|
2504
|
+
if (statement.kind == "ReturnStatement") {
|
|
2505
|
+
return Boolean(statement.expression && expressionContainsSignProducingOperation(statement.expression));
|
|
2506
|
+
}
|
|
435
2507
|
return false;
|
|
436
2508
|
});
|
|
437
2509
|
}
|
|
@@ -451,6 +2523,30 @@ function expressionContainsSignProducingOperation(expression) {
|
|
|
451
2523
|
if (expression.kind == "CallExpression") {
|
|
452
2524
|
return expression.arguments.some((argument) => expressionContainsSignProducingOperation(argument));
|
|
453
2525
|
}
|
|
2526
|
+
if (expression.kind == "RecordConstruction") {
|
|
2527
|
+
return expression.arguments.some((argument) => expressionContainsSignProducingOperation(argument));
|
|
2528
|
+
}
|
|
2529
|
+
if (expression.kind == "MemberRead")
|
|
2530
|
+
return expressionContainsSignProducingOperation(expression.receiver);
|
|
2531
|
+
if (expression.kind == "ListLiteral")
|
|
2532
|
+
return expression.elements.some((element) => expressionContainsSignProducingOperation(element));
|
|
2533
|
+
if (expression.kind == "MapLiteral" || expression.kind == "OrderedMapLiteral") {
|
|
2534
|
+
return expression.entries.some((entry) => expressionContainsSignProducingOperation(entry.key) ||
|
|
2535
|
+
expressionContainsSignProducingOperation(entry.value));
|
|
2536
|
+
}
|
|
2537
|
+
if (expression.kind == "ListIndexExpression") {
|
|
2538
|
+
return expressionContainsSignProducingOperation(expression.collection) || expressionContainsSignProducingOperation(expression.index);
|
|
2539
|
+
}
|
|
2540
|
+
if (expression.kind == "MapLookupExpression") {
|
|
2541
|
+
return expressionContainsSignProducingOperation(expression.collection) || expressionContainsSignProducingOperation(expression.key);
|
|
2542
|
+
}
|
|
2543
|
+
if (expression.kind == "CollectionSizeExpression")
|
|
2544
|
+
return expressionContainsSignProducingOperation(expression.collection);
|
|
2545
|
+
if (expression.kind == "OptionalSome")
|
|
2546
|
+
return expressionContainsSignProducingOperation(expression.value);
|
|
2547
|
+
if (expression.kind == "OptionalIsPresent" || expression.kind == "OptionalUnwrap") {
|
|
2548
|
+
return expressionContainsSignProducingOperation(expression.operand);
|
|
2549
|
+
}
|
|
454
2550
|
return false;
|
|
455
2551
|
}
|
|
456
2552
|
/**
|
|
@@ -469,4 +2565,4 @@ function binaryOperationSpelling(operation, language) {
|
|
|
469
2565
|
return syntax.strict;
|
|
470
2566
|
return syntax.default;
|
|
471
2567
|
}
|
|
472
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tlbmRzL3NoYXJlZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEQsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDNUQsT0FBTyxFQUFDLCtCQUErQixFQUFFLHdCQUF3QixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDMUYsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRTlDLDhGQUE4RjtBQUM5RixNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFBO0FBQ2pGLG9LQUFvSztBQUNwSyxNQUFNLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDMUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN6RCxZQUFZLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDO0lBQzNELGVBQWUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUM7SUFDOUQsU0FBUyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQztJQUN2RCxVQUFVLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQztJQUN6QyxZ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SUFDaEQsTUFBTSxlQUFlLEdBQUcsUUFBUSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2RyxRQUFRLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvRixDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUNwRixNQUFNLHVCQUF1QixHQUFHLFFBQVEsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDL0csUUFBUSxJQUFJLFFBQVEsSUFBSSxRQUFRLElBQUksTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNsRSxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUNwRixNQUFNLGtCQUFrQixHQUFHLFFBQVEsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFD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SUFDdEQsSUFBSSxRQUFRLElBQUksUUFBUSxJQUFJLE1BQU0sQ0FBQyxNQUFNO1FBQUUsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFBO0lBQy9ELElBQUksQ0FBQyxRQUFRLElBQUksS0FBSyxJQUFJLFFBQVEsSUFBSSxZQUFZLElBQUksUUFBUSxJQUFJLFlBQVksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxNQUFNO1FBQUUsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFBO0lBRXRILE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQTtBQUN2QixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7dW5zdXBwb3J0ZWRDYXBhYmlsaXR5fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge3ZhbGlkYXRlQmFja2VuZFR5cGVzfSBmcm9tIFwiLi4vc2VtYW50aWMvdmFsaWRhdGUuanNcIlxuaW1wb3J0IHt2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyLCB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXJ9IGZyb20gXCIuL2lkZW50aWZpZXJzLmpzXCJcbmltcG9ydCB7ZW1pdFN0cmluZ0xpdGVyYWx9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuXG4vKiogQHR5cGUge1JlYWRvbmx5PFJlY29yZDxpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1VuYXJ5T3BlcmF0aW9uLCBzdHJpbmc+Pn0gKi9cbmNvbnN0IHVuYXJ5T3BlcmF0aW9uU3ludGF4ID0gT2JqZWN0LmZyZWV6ZSh7Qm9vbGVhbk5vdDogXCIhXCIsIEludGVnZXJOZWdhdGU6IFwiLVwifSlcbi8qKiBAdHlwZSB7UmVhZG9ubHk8UmVjb3JkPGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljQmluYXJ5T3BlcmF0aW9uLCBSZWFkb25seTx7ZGVmYXVsdDogc3RyaW5nLCBwaHA/OiBzdHJpbmcsIHB5dGhvbj86IHN0cmluZywgc3RyaWN0Pzogc3RyaW5nfT4+Pn0gKi9cbmNvbnN0IGJpbmFyeU9wZXJhdGlvblN5bnRheCA9IE9iamVjdC5mcmVlemUoe1xuICBCb29sZWFuQW5kOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIiYmXCIsIHB5dGhvbjogXCJhbmRcIn0pLFxuICBCb29sZWFuRXF1YWw6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiPT1cIiwgc3RyaWN0OiBcIj09PVwifSksXG4gIEJvb2xlYW5Ob3RFcXVhbDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCIhPVwiLCBzdHJpY3Q6IFwiIT09XCJ9KSxcbiAgQm9vbGVhbk9yOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcInx8XCIsIHB5dGhvbjogXCJvclwifSksXG4gIEludGVnZXJBZGQ6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiK1wifSksXG4gIEludGVnZXJFcXVhbDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCI9PVwiLCBzdHJpY3Q6IFwiPT09XCJ9KSxcbiAgSW50ZWdlckdyZWF0ZXJUaGFuOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIj5cIn0pLFxuICBJbnRlZ2VyR3JlYXRlclRoYW5PckVxdWFsOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIj49XCJ9KSxcbiAgSW50ZWdlckxlc3NUaGFuOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIjxcIn0pLFxuICBJbnRlZ2VyTGVzc1RoYW5PckVxdWFsOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIjw9XCJ9KSxcbiAgSW50ZWdlck11bHRpcGx5OiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIipcIn0pLFxuICBJbnRlZ2VyTm90RXF1YWw6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiIT1cIiwgc3RyaWN0OiBcIiE9PVwifSksXG4gIEludGVnZXJTdWJ0cmFjdDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCItXCJ9KSxcbiAgU3RyaW5nQ29uY2F0OiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIitcIiwgcGhwOiBcIi5cIn0pLFxuICBTdHJpbmdFcXVhbDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCI9PVwiLCBzdHJpY3Q6IFwiPT09XCJ9KSxcbiAgU3RyaW5nTm90RXF1YWw6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiIT1cIiwgc3RyaWN0OiBcIiE9PVwifSlcbn0pXG5cbi8qKlxuICogQ2hlY2tzIHRoZSBpbnRlbnRpb25hbGx5IG5hcnJvdyBiYWNrZW5kIGNvbnRyYWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQmFja2VuZE1vZHVsZShtb2R1bGUsIGxhbmd1YWdlKSB7XG4gIGlmICghbW9kdWxlIHx8IHR5cGVvZiBtb2R1bGUgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KG1vZHVsZSkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBtb2R1bGVcIiwgdW5kZWZpbmVkKVxuICB9XG4gIGlmIChtb2R1bGUua2luZCAhPSBcIk1vZHVsZVwiKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIG1vZHVsZS5raW5kLCBtb2R1bGUubG9jYXRpb24pXG4gIGlmICghQXJyYXkuaXNBcnJheShtb2R1bGUuZnVuY3Rpb25zKSB8fCAhbW9kdWxlLmVudHJ5UG9pbnQgfHwgdHlwZW9mIG1vZHVsZS5lbnRyeVBvaW50ICE9IFwib2JqZWN0XCIgfHxcbiAgICBtb2R1bGUuZW50cnlQb2ludC5raW5kICE9IFwiRW50cnlQb2ludFwiKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIG1vZHVsZSBtZW1iZXJzXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgaWYgKG1vZHVsZS5mdW5jdGlvbnMubGVuZ3RoID09IDApIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtb2R1bGUgd2l0aG91dCBmdW5jdGlvbnNcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICB2YWxpZGF0ZUJsb2NrKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIGxhbmd1YWdlLCBtb2R1bGUuZW50cnlQb2ludC5sb2NhdGlvbilcblxuICBmb3IgKGNvbnN0IGZ1bmN0aW9uRGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgIGlmICghZnVuY3Rpb25EZWNsYXJhdGlvbiB8fCB0eXBlb2YgZnVuY3Rpb25EZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoZnVuY3Rpb25EZWNsYXJhdGlvbikgfHxcbiAgICAgIGZ1bmN0aW9uRGVjbGFyYXRpb24ua2luZCAhPSBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiB8fCAhQXJyYXkuaXNBcnJheShmdW5jdGlvbkRlY2xhcmF0aW9uLnBhcmFtZXRlcnMpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIGZ1bmN0aW9uIGRlY2xhcmF0aW9uXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVUYXJnZXRCaW5kaW5nSWRlbnRpZmllcihsYW5ndWFnZSwgZnVuY3Rpb25EZWNsYXJhdGlvbi5uYW1lLCBcImZ1bmN0aW9uXCIsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubG9jYXRpb24pXG5cbiAgICBpZiAoZnVuY3Rpb25EZWNsYXJhdGlvbi5wYXJhbWV0ZXJzLmxlbmd0aCAhPSAyKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiZnVuY3Rpb24gcGFyYW1ldGVyIGNvdW50IG90aGVyIHRoYW4gdHdvXCIsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlQmxvY2soZnVuY3Rpb25EZWNsYXJhdGlvbi5ib2R5LCBsYW5ndWFnZSwgZnVuY3Rpb25EZWNsYXJhdGlvbi5sb2NhdGlvbilcblxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIGZ1bmN0aW9uRGVjbGFyYXRpb24ucGFyYW1ldGVycykge1xuICAgICAgaWYgKCFwYXJhbWV0ZXIgfHwgdHlwZW9mIHBhcmFtZXRlciAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocGFyYW1ldGVyKSB8fCBwYXJhbWV0ZXIua2luZCAhPSBcIlBhcmFtZXRlclwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgcGFyYW1ldGVyXCIsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgICB2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyKGxhbmd1YWdlLCBwYXJhbWV0ZXIubmFtZSwgXCJwYXJhbWV0ZXJcIiwgcGFyYW1ldGVyLmxvY2F0aW9uKVxuICAgIH1cbiAgfVxuICB2YWxpZGF0ZVNjYWZmb2xkaW5nTmFtZXMobW9kdWxlLCBsYW5ndWFnZSlcbiAgdmFsaWRhdGVCYWNrZW5kVHlwZXMobW9kdWxlLCBsYW5ndWFnZSlcbn1cblxuLyoqXG4gKiBSZWplY3RzIHNlbWFudGljIG5hbWVzIHRoYXQgd291bGQgY2FwdHVyZSBzeW50YXggb3duZWQgYnkgb25lIGJhY2tlbmQgZW1pdHRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBCYWNrZW5kIGxhbmd1YWdlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlU2NhZmZvbGRpbmdOYW1lcyhtb2R1bGUsIGxhbmd1YWdlKSB7XG4gIGNvbnN0IG93bmVkRW50cnlOYW1lcyA9IGxhbmd1YWdlID09IFwiZ29cIiA/IG5ldyBTZXQoW1wiZm10XCIsIFwiaW50NjRcIiwgXCJib29sXCIsIFwic3RyaW5nXCIsIFwidHJ1ZVwiLCBcImZhbHNlXCJdKSA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiA/IG5ldyBTZXQoW1wiU3lzdGVtXCJdKSA6IGxhbmd1YWdlID09IFwiamF2YVwiID8gbmV3IFNldChbXCJhcmdzXCIsIFwiU3lzdGVtXCJdKSA6XG4gICAgW1wiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIl0uaW5jbHVkZXMobGFuZ3VhZ2UpID8gbmV3IFNldChbXCJjb25zb2xlXCJdKSA6IG5ldyBTZXQoKVxuICBjb25zdCBvd25lZFByaW50UmVjZWl2ZXJOYW1lcyA9IGxhbmd1YWdlID09IFwiZ29cIiA/IG5ldyBTZXQoW1wiZm10XCIsIFwiaW50NjRcIiwgXCJib29sXCIsIFwic3RyaW5nXCIsIFwidHJ1ZVwiLCBcImZhbHNlXCJdKSA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiB8fCBsYW5ndWFnZSA9PSBcImphdmFcIiA/IG5ldyBTZXQoW1wiU3lzdGVtXCJdKSA6XG4gICAgW1wiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIl0uaW5jbHVkZXMobGFuZ3VhZ2UpID8gbmV3IFNldChbXCJjb25zb2xlXCJdKSA6IG5ldyBTZXQoKVxuICBjb25zdCBvd25lZENhbGxhYmxlTmFtZXMgPSBsYW5ndWFnZSA9PSBcImdvXCIgPyBuZXcgU2V0KFtcIm1haW5cIiwgXCJpbml0XCIsIFwiZm10XCIsIFwiaW50NjRcIiwgXCJib29sXCIsIFwic3RyaW5nXCIsIFwidHJ1ZVwiLCBcImZhbHNlXCJdKSA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiA/IG5ldyBTZXQoW1xuICAgIFwiRXF1YWxzXCIsIFwiRmluYWxpemVcIiwgXCJHZXRIYXNoQ29kZVwiLCBcIkdldFR5cGVcIiwgXCJNYWluXCIsIFwiTWVtYmVyd2lzZUNsb25lXCIsIFwiUHJvZ3JhbVwiLCBcIlJlZmVyZW5jZUVxdWFsc1wiLCBcIlN5c3RlbVwiLCBcIlRvU3RyaW5nXCJcbiAgXSkgOlxuICAgIFtcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCJdLmluY2x1ZGVzKGxhbmd1YWdlKSA/IG5ldyBTZXQoW1wiY29uc29sZVwiXSkgOlxuICAgIGxhbmd1YWdlID09IFwicnVieVwiID8gbmV3IFNldChbXCJwdXRzXCJdKSA6IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGFsbFN0YXRlbWVudHMobW9kdWxlLmVudHJ5UG9pbnQuYm9keSkpIHtcbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgJiYgb3duZWRFbnRyeU5hbWVzLmhhcyhzdGF0ZW1lbnQubmFtZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGVudHJ5IGxvY2FsICcke3N0YXRlbWVudC5uYW1lfScgY2FwdHVyZXMgYmFja2VuZCBzY2FmZm9sZGluZ2AsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB7XG4gICAgaWYgKG93bmVkQ2FsbGFibGVOYW1lcy5oYXMoZGVjbGFyYXRpb24ubmFtZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGZ1bmN0aW9uICcke2RlY2xhcmF0aW9uLm5hbWV9JyBjYXB0dXJlcyBiYWNrZW5kIHNjYWZmb2xkaW5nYCwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMpIHtcbiAgICAgIGlmIChvd25lZFByaW50UmVjZWl2ZXJOYW1lcy5oYXMocGFyYW1ldGVyLm5hbWUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGZ1bmN0aW9uIHBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nIGNhcHR1cmVzIGJhY2tlbmQgc2NhZmZvbGRpbmdgLCBwYXJhbWV0ZXIubG9jYXRpb24pXG4gICAgICB9XG4gICAgfVxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGFsbFN0YXRlbWVudHMoZGVjbGFyYXRpb24uYm9keSkpIHtcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiAmJiBvd25lZFByaW50UmVjZWl2ZXJOYW1lcy5oYXMoc3RhdGVtZW50Lm5hbWUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGZ1bmN0aW9uIGxvY2FsICcke3N0YXRlbWVudC5uYW1lfScgY2FwdHVyZXMgYmFja2VuZCBzY2FmZm9sZGluZ2AsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGV2ZXJ5IHN0YXRlbWVudCBuZXN0ZWQgYmVuZWF0aCBhIGJsb2NrIGluIHNlbWFudGljIG9yZGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBTZW1hbnRpYyBibG9jay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnRbXX0gU3RhdGVtZW50cyBpbmNsdWRpbmcgbmVzdGVkIGJyYW5jaGVzLlxuICovXG5mdW5jdGlvbiBhbGxTdGF0ZW1lbnRzKGJsb2NrKSB7XG4gIHJldHVybiBibG9jay5zdGF0ZW1lbnRzLmZsYXRNYXAoKHN0YXRlbWVudCkgPT4gc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiXG4gICAgPyBbc3RhdGVtZW50LCAuLi5hbGxTdGF0ZW1lbnRzKHN0YXRlbWVudC5jb25zZXF1ZW50KSwgLi4uKHN0YXRlbWVudC5hbHRlcm5hdGUgPyBhbGxTdGF0ZW1lbnRzKHN0YXRlbWVudC5hbHRlcm5hdGUpIDogW10pXVxuICAgIDogW3N0YXRlbWVudF0pXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBjb21wbGV0ZSBzZW1hbnRpYyBibG9jayBiZWZvcmUgZW1pc3Npb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGJsb2NrIC0gQ2FuZGlkYXRlIGJsb2NrLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSBvd25lckxvY2F0aW9uIC0gRW5jbG9zaW5nIGxvY2F0aW9uLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlQmxvY2soYmxvY2ssIGxhbmd1YWdlLCBvd25lckxvY2F0aW9uKSB7XG4gIGlmICghYmxvY2sgfHwgdHlwZW9mIGJsb2NrICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShibG9jaykpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBibG9ja1wiLCBvd25lckxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKGJsb2NrKVxuICBjb25zdCBsb2NhdGlvbiA9IGNhbmRpZGF0ZS5sb2NhdGlvbiA/PyBvd25lckxvY2F0aW9uXG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IFwiQmxvY2tcIikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgYmxvY2sgJHtTdHJpbmcoUmVmbGVjdC5nZXQoYmxvY2ssIFwia2luZFwiKSl9YCwgbG9jYXRpb24pXG4gIGlmICghQXJyYXkuaXNBcnJheShjYW5kaWRhdGUuc3RhdGVtZW50cykpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgYmxvY2sgc3RhdGVtZW50c1wiLCBsb2NhdGlvbilcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBjYW5kaWRhdGUuc3RhdGVtZW50cykgdmFsaWRhdGVTdGF0ZW1lbnQoc3RhdGVtZW50LCBsYW5ndWFnZSwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBzdXBwb3J0ZWQgc3RhdGVtZW50IHJlY3Vyc2l2ZWx5LlxuICogQHBhcmFtIHt1bmtub3dufSBzdGF0ZW1lbnQgLSBDYW5kaWRhdGUgc3RhdGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSBvd25lckxvY2F0aW9uIC0gRW5jbG9zaW5nIGJvZHkgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVTdGF0ZW1lbnQoc3RhdGVtZW50LCBsYW5ndWFnZSwgb3duZXJMb2NhdGlvbikge1xuICBpZiAoIXN0YXRlbWVudCB8fCB0eXBlb2Ygc3RhdGVtZW50ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShzdGF0ZW1lbnQpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgc3RhdGVtZW50XCIsIG93bmVyTG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImtpbmRcIilcbiAgY29uc3QgbG9jYXRpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSAqLyAoXG4gICAgUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImxvY2F0aW9uXCIpID8/IG93bmVyTG9jYXRpb25cbiAgKVxuXG4gIGlmICh0eXBlb2Yga2luZCAhPSBcInN0cmluZ1wiKSByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBzdGF0ZW1lbnRcIiwgbG9jYXRpb24pXG4gIGlmIChraW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkxvY2FsRGVjbGFyYXRpb259ICovIChzdGF0ZW1lbnQpXG5cbiAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uLm11dGFibGUgIT0gXCJib29sZWFuXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJsb2NhbCBkZWNsYXJhdGlvbiB3aXRoIGludmFsaWQgbXV0YWJpbGl0eVwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVUYXJnZXRCaW5kaW5nSWRlbnRpZmllcihsYW5ndWFnZSwgZGVjbGFyYXRpb24ubmFtZSwgXCJsb2NhbFwiLCBsb2NhdGlvbilcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oZGVjbGFyYXRpb24uaW5pdGlhbGl6ZXIsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoa2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGFzc2lnbm1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkFzc2lnbm1lbnRTdGF0ZW1lbnR9ICovIChzdGF0ZW1lbnQpXG5cbiAgICB2YWxpZGF0ZUFzc2lnbm1lbnRUYXJnZXQoYXNzaWdubWVudC50YXJnZXQsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oYXNzaWdubWVudC5leHByZXNzaW9uLCBsYW5ndWFnZSwgbG9jYXRpb24pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIiB8fCBraW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiZXhwcmVzc2lvblwiKSwgbGFuZ3VhZ2UsIGxvY2F0aW9uKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChraW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGJyYW5jaCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9ICovIChzdGF0ZW1lbnQpXG5cbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oYnJhbmNoLmNvbmRpdGlvbiwgbGFuZ3VhZ2UsIGxvY2F0aW9uKVxuICAgIHZhbGlkYXRlQmxvY2soYnJhbmNoLmNvbnNlcXVlbnQsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICBpZiAoT2JqZWN0Lmhhc093bihicmFuY2gsIFwiYWx0ZXJuYXRlXCIpKSB2YWxpZGF0ZUJsb2NrKGJyYW5jaC5hbHRlcm5hdGUsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICByZXR1cm5cbiAgfVxuXG4gIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYHN0YXRlbWVudCAke2tpbmR9YCwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBzaW1wbGUgaWRlbnRpZmllciB0YXJnZXQgaW50cm9kdWNlZCBieSB0YXNrIDAwMi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdGFyZ2V0IC0gQ2FuZGlkYXRlIGFzc2lnbm1lbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSBvd25lckxvY2F0aW9uIC0gQXNzaWdubWVudCBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUFzc2lnbm1lbnRUYXJnZXQodGFyZ2V0LCBsYW5ndWFnZSwgb3duZXJMb2NhdGlvbikge1xuICBpZiAoIXRhcmdldCB8fCB0eXBlb2YgdGFyZ2V0ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheSh0YXJnZXQpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgYXNzaWdubWVudCB0YXJnZXRcIiwgb3duZXJMb2NhdGlvbilcbiAgfVxuXG4gIGNvbnN0IGNhbmRpZGF0ZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWRlbnRpZmllckV4cHJlc3Npb259ICovICh0YXJnZXQpXG4gIGNvbnN0IGxvY2F0aW9uID0gY2FuZGlkYXRlLmxvY2F0aW9uID8/IG93bmVyTG9jYXRpb25cblxuICBpZiAoY2FuZGlkYXRlLmtpbmQgIT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGFzc2lnbm1lbnQgdGFyZ2V0ICR7U3RyaW5nKFJlZmxlY3QuZ2V0KHRhcmdldCwgXCJraW5kXCIpKX1gLCBsb2NhdGlvbilcbiAgfVxuXG4gIHZhbGlkYXRlVGFyZ2V0QmluZGluZ0lkZW50aWZpZXIobGFuZ3VhZ2UsIGNhbmRpZGF0ZS5uYW1lLCBcImFzc2lnbm1lbnQgdGFyZ2V0XCIsIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIENoZWNrcyBleHByZXNzaW9uIGJhY2tlbmQgY2FwYWJpbGl0aWVzIHJlY3Vyc2l2ZWx5LlxuICogQHBhcmFtIHt1bmtub3dufSBleHByZXNzaW9uIC0gQ2FuZGlkYXRlIHNlbWFudGljIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gQmFja2VuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9IG93bmVyTG9jYXRpb24gLSBOZWFyZXN0IG93bmluZyBub2RlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtib29sZWFufSBbYWxsb3dKYXZhTmVnYXRlZE1pbmltdW1PcGVyYW5kXSAtIFdoZXRoZXIgSmF2YSBtYXkgdXNlIDIxNDc0ODM2NDggb25seSBiZW5lYXRoIGludGVnZXIgbmVnYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIGxhbmd1YWdlLCBvd25lckxvY2F0aW9uLCBhbGxvd0phdmFOZWdhdGVkTWluaW11bU9wZXJhbmQgPSBmYWxzZSkge1xuICBpZiAoIWV4cHJlc3Npb24gfHwgdHlwZW9mIGV4cHJlc3Npb24gIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGV4cHJlc3Npb24pKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgZXhwcmVzc2lvblwiLCBvd25lckxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoZXhwcmVzc2lvbilcbiAgY29uc3QgbG9jYXRpb24gPSBjYW5kaWRhdGUubG9jYXRpb24gPz8gb3duZXJMb2NhdGlvblxuXG4gIGlmICh0eXBlb2YgY2FuZGlkYXRlLmtpbmQgIT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIGV4cHJlc3Npb25cIiwgbG9jYXRpb24pXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgIHZhbGlkYXRlVGFyZ2V0SWRlbnRpZmllcihsYW5ndWFnZSwgY2FuZGlkYXRlLm5hbWUsIFwicmVmZXJlbmNlXCIsIGxvY2F0aW9uKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIpIHtcbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKGNhbmRpZGF0ZS52YWx1ZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJub24tc2FmZSBpbnRlZ2VyIGxpdGVyYWxcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHZhbGlkTmVnYXRlZE1pbmltdW1PcGVyYW5kID0gYWxsb3dKYXZhTmVnYXRlZE1pbmltdW1PcGVyYW5kICYmIGNhbmRpZGF0ZS52YWx1ZSA9PSAyMTQ3NDgzNjQ4XG5cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgJiYgIXZhbGlkTmVnYXRlZE1pbmltdW1PcGVyYW5kICYmIChjYW5kaWRhdGUudmFsdWUgPCAtMjE0NzQ4MzY0OCB8fCBjYW5kaWRhdGUudmFsdWUgPiAyMTQ3NDgzNjQ3KSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImludGVnZXIgbGl0ZXJhbCBvdXRzaWRlIHNpZ25lZCAzMi1iaXQgaW50IHJhbmdlXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoKGxhbmd1YWdlID09IFwiY3NoYXJwXCIgfHwgbGFuZ3VhZ2UgPT0gXCJnb1wiIHx8IGxhbmd1YWdlID09IFwiY1wiIHx8IGxhbmd1YWdlID09IFwiY3BwXCIpICYmIGNhbmRpZGF0ZS52YWx1ZSA8IDAgfHxcbiAgICAgIChsYW5ndWFnZSA9PSBcImNcIiB8fCBsYW5ndWFnZSA9PSBcImNwcFwiKSAmJiBPYmplY3QuaXMoY2FuZGlkYXRlLnZhbHVlLCAtMCkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJuZWdhdGl2ZSBpbnRlZ2VyIGxpdGVyYWwgd2l0aG91dCBzZW1hbnRpYyBuZWdhdGlvblwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiQm9vbGVhbkxpdGVyYWxcIiB8fCBjYW5kaWRhdGUua2luZCA9PSBcIlN0cmluZ0xpdGVyYWxcIikgcmV0dXJuXG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHtcbiAgICB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIGNhbmRpZGF0ZS5jYWxsZWUsIFwiY2FsbGVlXCIsIGxvY2F0aW9uKVxuICAgIGlmICghQXJyYXkuaXNBcnJheShjYW5kaWRhdGUuYXJndW1lbnRzKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBjYWxsIGFyZ3VtZW50c1wiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKGNhbmRpZGF0ZS5hcmd1bWVudHMubGVuZ3RoICE9IDIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJjYWxsIGFyZ3VtZW50IGNvdW50IG90aGVyIHRoYW4gdHdvXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIGNhbmRpZGF0ZS5hcmd1bWVudHMpIHZhbGlkYXRlRXhwcmVzc2lvbihhcmd1bWVudCwgbGFuZ3VhZ2UsIGxvY2F0aW9uKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKCFPYmplY3QuaGFzT3duKHVuYXJ5T3BlcmF0aW9uU3ludGF4LCBTdHJpbmcoY2FuZGlkYXRlLm9wZXJhdGlvbikpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB1bmFyeSBvcGVyYXRpb24gJHtTdHJpbmcoY2FuZGlkYXRlLm9wZXJhdGlvbil9YCwgbG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUub3BlcmFuZCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBjYW5kaWRhdGUub3BlcmF0aW9uID09IFwiSW50ZWdlck5lZ2F0ZVwiKVxuICAgIHZhbGlkYXRlS25vd25UYXJnZXRJbnRlZ2VyKGNhbmRpZGF0ZSwgbGFuZ3VhZ2UsIGxvY2F0aW9uKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikge1xuICAgIGlmICghT2JqZWN0Lmhhc093bihiaW5hcnlPcGVyYXRpb25TeW50YXgsIFN0cmluZyhjYW5kaWRhdGUub3BlcmF0aW9uKSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGJpbmFyeSBvcGVyYXRpb24gJHtTdHJpbmcoY2FuZGlkYXRlLm9wZXJhdGlvbil9YCwgbG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUubGVmdCwgbGFuZ3VhZ2UsIGxvY2F0aW9uKVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUucmlnaHQsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICB2YWxpZGF0ZUtub3duVGFyZ2V0SW50ZWdlcihjYW5kaWRhdGUsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICByZXR1cm5cbiAgfVxuXG4gIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgU3RyaW5nKFJlZmxlY3QuZ2V0KGV4cHJlc3Npb24sIFwia2luZFwiKSksIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFJlamVjdHMgY29tcGlsZS10aW1lLWtub3duIEphdmEgaW50ZWdlciBvcGVyYXRpb24gcmVzdWx0cyBvdXRzaWRlIHByaW1pdGl2ZSBpbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlVuYXJ5RXhwcmVzc2lvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJpbmFyeUV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBWYWxpZGF0ZWQgb3BlcmF0aW9uIHNoYXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSBsb2NhdGlvbiAtIE9wZXJhdGlvbiBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUtub3duVGFyZ2V0SW50ZWdlcihleHByZXNzaW9uLCBsYW5ndWFnZSwgbG9jYXRpb24pIHtcbiAgY29uc3QgdmFsdWUgPSBrbm93bkludGVnZXJWYWx1ZShleHByZXNzaW9uKVxuXG4gIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIiAmJiB2YWx1ZSAhPT0gdW5kZWZpbmVkICYmICh2YWx1ZSA8IC0yMTQ3NDgzNjQ4biB8fCB2YWx1ZSA+IDIxNDc0ODM2NDduKSkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJjb21waWxlLXRpbWUta25vd24gaW50ZWdlciBvcGVyYXRpb24gb3V0c2lkZSBzaWduZWQgMzItYml0IGludCByYW5nZVwiLCBsb2NhdGlvbilcbiAgfVxuICBpZiAoKGxhbmd1YWdlID09IFwiY3NoYXJwXCIgfHwgbGFuZ3VhZ2UgPT0gXCJnb1wiIHx8IGxhbmd1YWdlID09IFwiY1wiIHx8IGxhbmd1YWdlID09IFwiY3BwXCIpICYmIHZhbHVlICE9PSB1bmRlZmluZWQgJiZcbiAgICAodmFsdWUgPCAtOTIyMzM3MjAzNjg1NDc3NTgwOG4gfHwgdmFsdWUgPiA5MjIzMzcyMDM2ODU0Nzc1ODA3bikpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiY29tcGlsZS10aW1lLWtub3duIGludGVnZXIgb3BlcmF0aW9uIG91dHNpZGUgc2lnbmVkIDY0LWJpdCBsb25nIHJhbmdlXCIsIGxvY2F0aW9uKVxuICB9XG59XG5cbi8qKlxuICogRXZhbHVhdGVzIG9ubHkgbGl0ZXJhbCBpbnRlZ2VyLW9wZXJhdGlvbiB0cmVlcyBmb3IgYm91bmRzIHZhbGlkYXRpb24sIG5ldmVyIElSIGZvbGRpbmcuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICogQHJldHVybnMge2JpZ2ludCB8IHVuZGVmaW5lZH0gS25vd24gbWF0aGVtYXRpY2FsIGludGVnZXIuXG4gKi9cbmZ1bmN0aW9uIGtub3duSW50ZWdlclZhbHVlKGV4cHJlc3Npb24pIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkludGVnZXJMaXRlcmFsXCIgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIoZXhwcmVzc2lvbi52YWx1ZSkpIHJldHVybiBCaWdJbnQoZXhwcmVzc2lvbi52YWx1ZSlcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiICYmIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlck5lZ2F0ZVwiKSB7XG4gICAgY29uc3Qgb3BlcmFuZCA9IGtub3duSW50ZWdlclZhbHVlKGV4cHJlc3Npb24ub3BlcmFuZClcblxuICAgIHJldHVybiBvcGVyYW5kID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiAtb3BlcmFuZFxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHJldHVybiB1bmRlZmluZWRcblxuICBjb25zdCBsZWZ0ID0ga25vd25JbnRlZ2VyVmFsdWUoZXhwcmVzc2lvbi5sZWZ0KVxuICBjb25zdCByaWdodCA9IGtub3duSW50ZWdlclZhbHVlKGV4cHJlc3Npb24ucmlnaHQpXG5cbiAgaWYgKGxlZnQgPT09IHVuZGVmaW5lZCB8fCByaWdodCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5kZWZpbmVkXG4gIGlmIChleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkludGVnZXJBZGRcIikgcmV0dXJuIGxlZnQgKyByaWdodFxuICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyU3VidHJhY3RcIikgcmV0dXJuIGxlZnQgLSByaWdodFxuICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyTXVsdGlwbHlcIikgcmV0dXJuIGxlZnQgKiByaWdodFxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBFbWl0cyBhIHN1cHBvcnRlZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3dyaXRlci5qc1wiKS5Tb3VyY2VXcml0ZXJ9IHdyaXRlciAtIFNvdXJjZS1hd2FyZSB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBFeGFjdCBKU09OIFBvaW50ZXIgZm9yIHRoaXMgZXhwcmVzc2lvbiBvY2N1cnJlbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7KG5hbWU6IHN0cmluZykgPT4gc3RyaW5nfSBlbWl0SWRlbnRpZmllciAtIElkZW50aWZpZXIgZm9ybWF0dGVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24sIHBhdGgsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcikge1xuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgIHdyaXRlci5tYXBwZWQoZW1pdElkZW50aWZpZXIoZXhwcmVzc2lvbi5uYW1lKSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwibmFtZVwifSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiSW50ZWdlckxpdGVyYWxcIikge1xuICAgIGNvbnN0IHNwZWxsaW5nID0gbGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiA/IGAke2V4cHJlc3Npb24udmFsdWV9TGAgOiBTdHJpbmcoZXhwcmVzc2lvbi52YWx1ZSlcblxuICAgIHdyaXRlci5tYXBwZWQoc3BlbGxpbmcsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcImxpdGVyYWxcIn0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJvb2xlYW5MaXRlcmFsXCIpIHtcbiAgICBjb25zdCBzcGVsbGluZyA9IGxhbmd1YWdlID09IFwicHl0aG9uXCIgPyBleHByZXNzaW9uLnZhbHVlID8gXCJUcnVlXCIgOiBcIkZhbHNlXCIgOiBleHByZXNzaW9uLnZhbHVlID8gXCJ0cnVlXCIgOiBcImZhbHNlXCJcblxuICAgIHdyaXRlci5tYXBwZWQoc3BlbGxpbmcsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcImxpdGVyYWxcIn0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlN0cmluZ0xpdGVyYWxcIikge1xuICAgIHdyaXRlci5tYXBwZWQoZW1pdFN0cmluZ0xpdGVyYWwobGFuZ3VhZ2UsIGV4cHJlc3Npb24udmFsdWUpLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJsaXRlcmFsXCJ9KVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgd3JpdGVyLm1hcHBlZChleHByZXNzaW9uLmNhbGxlZSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwiY2FsbGVlXCJ9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIoXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaCgoYXJndW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJhcmd1bWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGFyZ3VtZW50LCBgJHtwYXRofS9hcmd1bWVudHMvJHtpbmRleH1gLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgfSlcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKGxhbmd1YWdlID09IFwiY3NoYXJwXCIgJiYgZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyTmVnYXRlXCIpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQoXCJjaGVja2VkKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgICAgd3JpdGVyLm1hcHBlZChcIi1cIiwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwicHl0aG9uXCIgJiYgZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJCb29sZWFuTm90XCIgPyBcIm5vdCBcIiA6IHVuYXJ5T3BlcmF0aW9uU3ludGF4W2V4cHJlc3Npb24ub3BlcmF0aW9uXSwge1xuICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwiXG4gICAgfSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKGxhbmd1YWdlID09IFwiY3NoYXJwXCIgJiYgW1wiSW50ZWdlckFkZFwiLCBcIkludGVnZXJTdWJ0cmFjdFwiLCBcIkludGVnZXJNdWx0aXBseVwiXS5pbmNsdWRlcyhleHByZXNzaW9uLm9wZXJhdGlvbikpIHtcbiAgICB3cml0ZXIubWFwcGVkKFwiY2hlY2tlZChcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIuc3ludGhldGljKFwiIFwiLCBcIm9wZXJhdG9yIHNwYWNpbmdcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgd3JpdGVyLm1hcHBlZChiaW5hcnlPcGVyYXRpb25TcGVsbGluZyhleHByZXNzaW9uLm9wZXJhdGlvbiwgbGFuZ3VhZ2UpLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm9wZXJhdG9yXCJcbiAgICB9KVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwib3BlcmF0b3Igc3BhY2luZ1wiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ucmlnaHQsIGAke3BhdGh9L3JpZ2h0YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgJiYgKGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nRXF1YWxcIiB8fCBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ05vdEVxdWFsXCIpKSB7XG4gICAgY29uc3QgY29tcG9zaXRlT3BlcmF0b3IgPSBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ05vdEVxdWFsXCIgJiYgd3JpdGVyLmhhc1JhbmdlKGV4cHJlc3Npb24sIHBhdGgsIFwiZXF1YWxpdHlPcGVyYXRvclwiKVxuXG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdOb3RFcXVhbFwiKSB7XG4gICAgICB3cml0ZXIubWFwcGVkKFwiIVwiLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwifSlcbiAgICB9XG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIuZXF1YWxzXCIsIHtcbiAgICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IGNvbXBvc2l0ZU9wZXJhdG9yID8gXCJlcXVhbGl0eU9wZXJhdG9yXCIgOiBcIm9wZXJhdG9yXCJcbiAgICB9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIoXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLnJpZ2h0LCBgJHtwYXRofS9yaWdodGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cblxuICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJvcGVyYXRvciBzcGFjaW5nXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICBjb25zdCBzcGVsbGluZyA9IGJpbmFyeU9wZXJhdGlvblNwZWxsaW5nKGV4cHJlc3Npb24ub3BlcmF0aW9uLCBsYW5ndWFnZSlcblxuICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdOb3RFcXVhbFwiICYmIHdyaXRlci5oYXNSYW5nZShleHByZXNzaW9uLCBwYXRoLCBcImVxdWFsaXR5T3BlcmF0b3JcIikpIHtcbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLnNsaWNlKDAsIDEpLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwifSlcbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLnNsaWNlKDEpLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJlcXVhbGl0eU9wZXJhdG9yXCJ9KVxuICB9IGVsc2Ugd3JpdGVyLm1hcHBlZChzcGVsbGluZywge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwib3BlcmF0b3Igc3BhY2luZ1wiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLnJpZ2h0LCBgJHtwYXRofS9yaWdodGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbn1cblxuLyoqXG4gKiBSZXBvcnRzIHdoZXRoZXIgSmF2YVNjcmlwdC1mYW1pbHkgZXhlY3V0aW9uIGNhbiBjcmVhdGUgSUVFRS03NTQgc2lnbmVkIHplcm8uXG4gKiBTZW1hbnRpZm9sZCBpbnRlZ2VycyBoYXZlIG9uZSBtYXRoZW1hdGljYWwgemVybywgc28gdGhvc2UgdGFyZ2V0cyBjYW5vbmljYWxpemVcbiAqIHRoZWlyIG9ic2VydmFibGUgc2NhbGFyIG91dHB1dCB3aXRob3V0IGNoYW5naW5nIHRoZSBvcGVyYXRpb24gdHJlZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFZhbGlkYXRlZCBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBjYW5vbmljYWwgb3V0cHV0IHJlbmRlcmluZyBpcyByZXF1aXJlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVzQ2Fub25pY2FsWmVyb1JlbmRlcmluZyhtb2R1bGUpIHtcbiAgcmV0dXJuIG1vZHVsZS5mdW5jdGlvbnMuc29tZSgoZGVjbGFyYXRpb24pID0+IGJsb2NrQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGRlY2xhcmF0aW9uLmJvZHkpKSB8fFxuICAgIGJsb2NrQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKG1vZHVsZS5lbnRyeVBvaW50LmJvZHkpXG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBibG9jayBmb3Igc2lnbi1wcm9kdWNpbmcgaW50ZWdlciBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBTZW1hbnRpYyBibG9jay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIGEgbmVzdGVkIGV4cHJlc3Npb24gY2FuIHByb2R1Y2Ugc2lnbmVkIHplcm8gaW4gSmF2YVNjcmlwdC5cbiAqL1xuZnVuY3Rpb24gYmxvY2tDb250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oYmxvY2spIHtcbiAgcmV0dXJuIGJsb2NrLnN0YXRlbWVudHMuc29tZSgoc3RhdGVtZW50KSA9PiB7XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50LmNvbmRpdGlvbikgfHxcbiAgICAgICAgYmxvY2tDb250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50LmNvbnNlcXVlbnQpIHx8XG4gICAgICAgIEJvb2xlYW4oc3RhdGVtZW50LmFsdGVybmF0ZSAmJiBibG9ja0NvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuYWx0ZXJuYXRlKSlcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIpXG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUmV0dXJuU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiKSB7XG4gICAgICByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfSlcbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGV4cHJlc3Npb24gdHJlZSBmb3Igc2lnbi1wcm9kdWNpbmcgaW50ZWdlciBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoaXMgdHJlZSBjb250YWlucyBpbnRlZ2VyIG5lZ2F0aW9uIG9yIG11bHRpcGxpY2F0aW9uLlxuICovXG5mdW5jdGlvbiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24pIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlck5lZ2F0ZVwiIHx8IGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oZXhwcmVzc2lvbi5vcGVyYW5kKVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHtcbiAgICByZXR1cm4gZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyTXVsdGlwbHlcIiB8fCBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24ubGVmdCkgfHxcbiAgICAgIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oZXhwcmVzc2lvbi5yaWdodClcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uLmFyZ3VtZW50cy5zb21lKChhcmd1bWVudCkgPT4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihhcmd1bWVudCkpXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBNYXBzIG9uZSBhbHJlYWR5IHZhbGlkYXRlZCBzZW1hbnRpYyBvcGVyYXRpb24gdG8gdGFyZ2V0IHN5bnRheC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNCaW5hcnlPcGVyYXRpb259IG9wZXJhdGlvbiAtIENsb3NlZCBzZW1hbnRpYyBvcGVyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHJldHVybnMge3N0cmluZ30gVGFyZ2V0IG9wZXJhdG9yIHNwZWxsaW5nLlxuICovXG5mdW5jdGlvbiBiaW5hcnlPcGVyYXRpb25TcGVsbGluZyhvcGVyYXRpb24sIGxhbmd1YWdlKSB7XG4gIGNvbnN0IHN5bnRheCA9IGJpbmFyeU9wZXJhdGlvblN5bnRheFtvcGVyYXRpb25dXG5cbiAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIgJiYgc3ludGF4LnBocCkgcmV0dXJuIHN5bnRheC5waHBcbiAgaWYgKGxhbmd1YWdlID09IFwicHl0aG9uXCIgJiYgc3ludGF4LnB5dGhvbikgcmV0dXJuIHN5bnRheC5weXRob25cbiAgaWYgKChsYW5ndWFnZSA9PSBcInBocFwiIHx8IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiKSAmJiBzeW50YXguc3RyaWN0KSByZXR1cm4gc3ludGF4LnN0cmljdFxuXG4gIHJldHVybiBzeW50YXguZGVmYXVsdFxufVxuIl19
|
|
2568
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2JhY2tlbmRzL3NoYXJlZC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDdEQsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGFBQWEsQ0FBQTtBQUN4QyxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUM1RCxPQUFPLEVBQUMsK0JBQStCLEVBQUUsd0JBQXdCLEVBQUUsNEJBQTRCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUN4SCxPQUFPLEVBQUMsY0FBYyxFQUFFLGlCQUFpQixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRTlELDhGQUE4RjtBQUM5RixNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxVQUFVLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxHQUFHLEVBQUMsQ0FBQyxDQUFBO0FBQ2pGLG9LQUFvSztBQUNwSyxNQUFNLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7SUFDMUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUMsQ0FBQztJQUN6RCxZQUFZLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDO0lBQzNELGVBQWUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUM7SUFDOUQsU0FBUyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUMsQ0FBQztJQUN2RCxVQUFVLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQztJQUN6QyxZQUFZLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDO0lBQzNELGtCQUFrQixFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFDLENBQUM7SUFDakQseUJBQXlCLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUMsQ0FBQztJQUN6RCxlQUFlLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUMsQ0FBQztJQUM5QyxzQkFBc0IsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQyxDQUFDO0lBQ3RELGVBQWUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLEdBQUcsRUFBQyxDQUFDO0lBQzlDLGVBQWUsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUM7SUFDOUQsZUFBZSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFDLENBQUM7SUFDOUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUMsQ0FBQztJQUNyRCxXQUFXLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBQyxDQUFDO0lBQzFELGNBQWMsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFDLENBQUM7Q0FDOUQsQ0FBQyxDQUFBO0FBQ0YsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtBQUM3RixNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDckYsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBQ3JGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtBQUNyRixNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDckYsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFlBQVksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0FBQ3JGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtBQUNyRixNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDckYsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUs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TUFBTTtRQUFFLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQTtJQUV0SCxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUE7QUFDdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQge3Vuc3VwcG9ydGVkQ2FwYWJpbGl0eX0gZnJvbSBcIi4uL2RpYWdub3N0aWMuanNcIlxuaW1wb3J0IHtpc0RlbnNlQXJyYXl9IGZyb20gXCIuLi9hcnJheS5qc1wiXG5pbXBvcnQge3ZhbGlkYXRlQmFja2VuZFR5cGVzfSBmcm9tIFwiLi4vc2VtYW50aWMvdmFsaWRhdGUuanNcIlxuaW1wb3J0IHt2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyLCB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIsIHZhbGlkYXRlVGFyZ2V0VHlwZUlkZW50aWZpZXJ9IGZyb20gXCIuL2lkZW50aWZpZXJzLmpzXCJcbmltcG9ydCB7ZW1pdFNjYWxhclR5cGUsIGVtaXRTdHJpbmdMaXRlcmFsfSBmcm9tIFwiLi9zY2FsYXJzLmpzXCJcblxuLyoqIEB0eXBlIHtSZWFkb25seTxSZWNvcmQ8aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNVbmFyeU9wZXJhdGlvbiwgc3RyaW5nPj59ICovXG5jb25zdCB1bmFyeU9wZXJhdGlvblN5bnRheCA9IE9iamVjdC5mcmVlemUoe0Jvb2xlYW5Ob3Q6IFwiIVwiLCBJbnRlZ2VyTmVnYXRlOiBcIi1cIn0pXG4vKiogQHR5cGUge1JlYWRvbmx5PFJlY29yZDxpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0JpbmFyeU9wZXJhdGlvbiwgUmVhZG9ubHk8e2RlZmF1bHQ6IHN0cmluZywgcGhwPzogc3RyaW5nLCBweXRob24/OiBzdHJpbmcsIHN0cmljdD86IHN0cmluZ30+Pj59ICovXG5jb25zdCBiaW5hcnlPcGVyYXRpb25TeW50YXggPSBPYmplY3QuZnJlZXplKHtcbiAgQm9vbGVhbkFuZDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCImJlwiLCBweXRob246IFwiYW5kXCJ9KSxcbiAgQm9vbGVhbkVxdWFsOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIj09XCIsIHN0cmljdDogXCI9PT1cIn0pLFxuICBCb29sZWFuTm90RXF1YWw6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiIT1cIiwgc3RyaWN0OiBcIiE9PVwifSksXG4gIEJvb2xlYW5PcjogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCJ8fFwiLCBweXRob246IFwib3JcIn0pLFxuICBJbnRlZ2VyQWRkOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIitcIn0pLFxuICBJbnRlZ2VyRXF1YWw6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiPT1cIiwgc3RyaWN0OiBcIj09PVwifSksXG4gIEludGVnZXJHcmVhdGVyVGhhbjogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCI+XCJ9KSxcbiAgSW50ZWdlckdyZWF0ZXJUaGFuT3JFcXVhbDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCI+PVwifSksXG4gIEludGVnZXJMZXNzVGhhbjogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCI8XCJ9KSxcbiAgSW50ZWdlckxlc3NUaGFuT3JFcXVhbDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCI8PVwifSksXG4gIEludGVnZXJNdWx0aXBseTogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCIqXCJ9KSxcbiAgSW50ZWdlck5vdEVxdWFsOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIiE9XCIsIHN0cmljdDogXCIhPT1cIn0pLFxuICBJbnRlZ2VyU3VidHJhY3Q6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiLVwifSksXG4gIFN0cmluZ0NvbmNhdDogT2JqZWN0LmZyZWV6ZSh7ZGVmYXVsdDogXCIrXCIsIHBocDogXCIuXCJ9KSxcbiAgU3RyaW5nRXF1YWw6IE9iamVjdC5mcmVlemUoe2RlZmF1bHQ6IFwiPT1cIiwgc3RyaWN0OiBcIj09PVwifSksXG4gIFN0cmluZ05vdEVxdWFsOiBPYmplY3QuZnJlZXplKHtkZWZhdWx0OiBcIiE9XCIsIHN0cmljdDogXCIhPT1cIn0pXG59KVxuY29uc3QgdGFzazAwNUxhbmd1YWdlcyA9IG5ldyBTZXQoW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiLCBcImRhcnRcIl0pXG5jb25zdCB0YXNrMDA2TGFuZ3VhZ2VzID0gbmV3IFNldChbXCJwaHBcIiwgXCJydWJ5XCIsIFwiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIiwgXCJqYXZhXCJdKVxuY29uc3QgdGFzazAwN0xhbmd1YWdlcyA9IG5ldyBTZXQoW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiXSlcbmNvbnN0IHRhc2swMDhMYW5ndWFnZXMgPSBuZXcgU2V0KFtcInBocFwiLCBcInJ1YnlcIiwgXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiLCBcImphdmFcIl0pXG5jb25zdCB0YXNrMDA5TGFuZ3VhZ2VzID0gbmV3IFNldChbXCJwaHBcIiwgXCJydWJ5XCIsIFwiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIiwgXCJqYXZhXCJdKVxuY29uc3QgdGFzazAxMUxhbmd1YWdlcyA9IG5ldyBTZXQoW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiXSlcbmNvbnN0IHRhc2swMTJMYW5ndWFnZXMgPSBuZXcgU2V0KFtcInBocFwiLCBcInJ1YnlcIiwgXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiLCBcImphdmFcIl0pXG5jb25zdCB0YXNrMDE0TGFuZ3VhZ2VzID0gbmV3IFNldChbXCJwaHBcIiwgXCJydWJ5XCIsIFwiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIiwgXCJqYXZhXCJdKVxuY29uc3QgdGFzazAzMkxhbmd1YWdlcyA9IG5ldyBTZXQoW1wicGhwXCIsIFwicnVieVwiLCBcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCIsIFwiamF2YVwiXSlcbmNvbnN0IHRhc2swMzNMYW5ndWFnZXMgPSBuZXcgU2V0KFtcInBocFwiLCBcInJ1YnlcIiwgXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiLCBcImphdmFcIl0pXG5jb25zdCBqYXZhUmVmZXJlbmNlTWV0aG9kSG9va3MgPSBuZXcgU2V0KFtcImNsb25lXCIsIFwiZXF1YWxzXCIsIFwiZmluYWxpemVcIiwgXCJnZXRDbGFzc1wiLCBcImhhc2hDb2RlXCIsIFwibm90aWZ5XCIsIFwibm90aWZ5QWxsXCIsIFwidG9TdHJpbmdcIiwgXCJ3YWl0XCJdKVxuY29uc3QgamF2YXNjcmlwdFJlZmVyZW5jZU1ldGhvZEhvb2tzID0gbmV3IFNldChbXG4gIFwiX19kZWZpbmVHZXR0ZXJfX1wiLCBcIl9fZGVmaW5lU2V0dGVyX19cIiwgXCJfX2xvb2t1cEdldHRlcl9fXCIsIFwiX19sb29rdXBTZXR0ZXJfX1wiLCBcIl9fcHJvdG9fX1wiLCBcImNvbnN0cnVjdG9yXCIsXG4gIFwiaGFzT3duUHJvcGVydHlcIiwgXCJpc1Byb3RvdHlwZU9mXCIsIFwicHJvcGVydHlJc0VudW1lcmFibGVcIiwgXCJ0b0xvY2FsZVN0cmluZ1wiLCBcInRvU3RyaW5nXCIsIFwidmFsdWVPZlwiXG5dKVxuY29uc3QgcnVieVJlZmVyZW5jZU1ldGhvZEhvb2tzID0gbmV3IFNldChbXG4gIFwiX19zZW5kX19cIiwgXCJleHRlbmRcIiwgXCJmZXRjaFwiLCBcImluc3RhbmNlX2V2YWxcIiwgXCJpbnN0YW5jZV9leGVjXCIsIFwibWV0aG9kXCIsIFwibWV0aG9kX21pc3NpbmdcIiwgXCJwdWJsaWNfc2VuZFwiLFxuICBcInJlc3BvbmRfdG9fbWlzc2luZz9cIiwgXCJzZW5kXCIsIFwic2luZ2xldG9uX2NsYXNzXCIsIFwic2l6ZVwiXG5dKVxuY29uc3QgamF2YU9iamVjdEluc3RhbmNlTWV0aG9kU2lnbmF0dXJlcyA9IG5ldyBTZXQoW1xuICBcImNsb25lKClcIiwgXCJlcXVhbHMoT2JqZWN0KVwiLCBcImZpbmFsaXplKClcIiwgXCJnZXRDbGFzcygpXCIsIFwiaGFzaENvZGUoKVwiLCBcIm5vdGlmeSgpXCIsIFwibm90aWZ5QWxsKClcIiwgXCJ0b1N0cmluZygpXCIsXG4gIFwid2FpdCgpXCIsIFwid2FpdChsb25nKVwiLCBcIndhaXQobG9uZyxpbnQpXCJcbl0pXG5cbi8qKlxuICogQ2hlY2tzIHRoZSBpbnRlbnRpb25hbGx5IG5hcnJvdyBiYWNrZW5kIGNvbnRyYWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gQmFja2VuZCBsYW5ndWFnZSBvciBiaW5hcnkgdGFyZ2V0LlxuICogQHBhcmFtIHt7ZXh0ZXJuYWxEZWNsYXJhdGlvbklkcz86IFNldDxzdHJpbmc+LCBwcm9ncmFtPzogYm9vbGVhbiwgdmlzaWJsZUZ1bmN0aW9ucz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb24+LCB2aXNpYmxlUmVjb3Jkcz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPiwgdmlzaWJsZUNsYXNzZXM/OiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPiwgdmlzaWJsZUVycm9ycz86IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+LCB2aXNpYmxlQ2FsbEVmZmVjdHM/OiBNYXA8c3RyaW5nLCBTZXQ8c3RyaW5nPj59fSBbb3B0aW9uc10gLSBSZXNvbHZlZCBwcm9ncmFtIHZhbGlkYXRpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVCYWNrZW5kTW9kdWxlKG1vZHVsZSwgbGFuZ3VhZ2UsIG9wdGlvbnMgPSB7fSkge1xuICBpZiAoIW1vZHVsZSB8fCB0eXBlb2YgbW9kdWxlICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShtb2R1bGUpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgbW9kdWxlXCIsIHVuZGVmaW5lZClcbiAgfVxuICBpZiAobW9kdWxlLmtpbmQgIT0gXCJNb2R1bGVcIikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBtb2R1bGUua2luZCwgbW9kdWxlLmxvY2F0aW9uKVxuICBpZiAoIUFycmF5LmlzQXJyYXkobW9kdWxlLmZ1bmN0aW9ucykgfHwgIW1vZHVsZS5lbnRyeVBvaW50IHx8IHR5cGVvZiBtb2R1bGUuZW50cnlQb2ludCAhPSBcIm9iamVjdFwiIHx8XG4gICAgbW9kdWxlLmVudHJ5UG9pbnQua2luZCAhPSBcIkVudHJ5UG9pbnRcIikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBtb2R1bGUgbWVtYmVyc1wiLCBtb2R1bGUubG9jYXRpb24pXG4gIGNvbnN0IGRlY2xhcmVkUmVjb3JkcyA9IG1vZHVsZS5yZWNvcmRzXG4gIGNvbnN0IHJlY29yZHMgPSBkZWNsYXJlZFJlY29yZHMgPT09IHVuZGVmaW5lZCA/IFtdIDogZGVjbGFyZWRSZWNvcmRzXG4gIGNvbnN0IGRlY2xhcmVkQ2xhc3NlcyA9IG1vZHVsZS5jbGFzc2VzXG4gIGNvbnN0IGNsYXNzZXMgPSBkZWNsYXJlZENsYXNzZXMgPT09IHVuZGVmaW5lZCA/IFtdIDogZGVjbGFyZWRDbGFzc2VzXG4gIGNvbnN0IGRlY2xhcmVkRXJyb3JzID0gbW9kdWxlLmVycm9yc1xuICBjb25zdCBlcnJvcnMgPSBkZWNsYXJlZEVycm9ycyA9PT0gdW5kZWZpbmVkID8gW10gOiBkZWNsYXJlZEVycm9yc1xuXG4gIGlmICghQXJyYXkuaXNBcnJheShyZWNvcmRzKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCByZWNvcmQgZGVjbGFyYXRpb25zXCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgaWYgKCFBcnJheS5pc0FycmF5KGNsYXNzZXMpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIHJlZmVyZW5jZSBjbGFzcyBkZWNsYXJhdGlvbnNcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICBpZiAoIUFycmF5LmlzQXJyYXkoZXJyb3JzKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBlcnJvciBkZWNsYXJhdGlvbnNcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICBpZiAobW9kdWxlLmZ1bmN0aW9ucy5sZW5ndGggPT0gMCAmJiAoIW9wdGlvbnMucHJvZ3JhbSB8fFxuICAgIHJlY29yZHMubGVuZ3RoID09IDAgJiYgY2xhc3Nlcy5sZW5ndGggPT0gMCAmJiBlcnJvcnMubGVuZ3RoID09IDAgJiYgbW9kdWxlLmVudHJ5UG9pbnQuYm9keT8uc3RhdGVtZW50cz8ubGVuZ3RoID09IDApKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1vZHVsZSB3aXRob3V0IGRlY2xhcmF0aW9ucyBvciBleGVjdXRhYmxlIGVudHJ5XCIsIG1vZHVsZS5sb2NhdGlvbilcbiAgfVxuICBpZiAoIXRhc2swMTJMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSAmJiBtb2R1bGVIYXNUeXBlUGFyYW1ldGVycyhtb2R1bGUpKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDEyIHR5cGUgcGFyYW1ldGVycyBhbmQgZ2VuZXJpYyBkZWNsYXJhdGlvbnNcIiwgbW9kdWxlLmxvY2F0aW9uKVxuICB9XG4gIGlmIChyZWNvcmRzLmxlbmd0aCA+IDAgJiYgIXRhc2swMDlMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSkge1xuICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwOSBjbG9zZWQgcmVjb3Jkc1wiLCByZWNvcmRzWzBdPy5sb2NhdGlvbiA/PyBtb2R1bGUubG9jYXRpb24pXG4gIH1cbiAgaWYgKGNsYXNzZXMubGVuZ3RoID4gMCAmJiAhdGFzazAzM0xhbmd1YWdlcy5oYXMobGFuZ3VhZ2UpKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDMzIHJlZmVyZW5jZSBjbGFzc2VzLCBtZXRob2RzLCBhbmQgY29uc3RydWN0b3JzXCIsIGNsYXNzZXNbMF0/LmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgfVxuICBpZiAoIXRhc2swMTFMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSkgcmVqZWN0VHlwZWRFcnJvcnMobW9kdWxlLCBsYW5ndWFnZSlcbiAgaWYgKCF0YXNrMDMyTGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHJlamVjdENvbmRpdGlvbkNvbnRyb2xsZWRMb29wcyhtb2R1bGUsIGxhbmd1YWdlKVxuICBpZiAoIXRhc2swMTRMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSkgcmVqZWN0T3JkZXJlZE1hcENhcGFiaWxpdHkobW9kdWxlLCBsYW5ndWFnZSlcbiAgdmFsaWRhdGVSZWNvcmRUYXJnZXRzKHJlY29yZHMsIG1vZHVsZS5mdW5jdGlvbnMsIGxhbmd1YWdlLCBtb2R1bGUubG9jYXRpb24pXG4gIHZhbGlkYXRlUmVmZXJlbmNlQ2xhc3NUYXJnZXRzKGNsYXNzZXMsIHJlY29yZHMsIGVycm9ycywgbW9kdWxlLmZ1bmN0aW9ucywgbGFuZ3VhZ2UsIG1vZHVsZS5sb2NhdGlvbilcbiAgaWYgKCF0YXNrMDA4TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHJlamVjdEl0ZXJhdGlvblN0YXRlbWVudHMobW9kdWxlLCBsYW5ndWFnZSlcbiAgaWYgKCF0YXNrMDA3TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHJlamVjdE9wdGlvbmFsVHlwZXMobW9kdWxlLCBsYW5ndWFnZSlcbiAgaWYgKCF0YXNrMDA2TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHJlamVjdENvbGxlY3Rpb25UeXBlcyhtb2R1bGUsIGxhbmd1YWdlKVxuICBjb25zdCBsb29wT3duZXJzID0gY29sbGVjdExvb3BPd25lcnMobW9kdWxlLCBsYW5ndWFnZSlcblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGNsYXNzZXMpIHtcbiAgICB2YWxpZGF0ZUJsb2NrKGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLmJvZHksIGxhbmd1YWdlLCBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5sb2NhdGlvbixcbiAgICAgIHthY3RpdmU6IFtdLCBvd25lcjogZGVjbGFyYXRpb24uY29uc3RydWN0b3IsIG93bmVyczogbG9vcE93bmVyc30sIG5ldyBTZXQoKSwgb3B0aW9ucy5leHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIHtcbiAgICAgIHZhbGlkYXRlQmxvY2sobWV0aG9kLmJvZHksIGxhbmd1YWdlLCBtZXRob2QubG9jYXRpb24sXG4gICAgICAgIHthY3RpdmU6IFtdLCBvd25lcjogbWV0aG9kLCBvd25lcnM6IGxvb3BPd25lcnN9LCBuZXcgU2V0KCksIG9wdGlvbnMuZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB9XG4gIH1cblxuICB2YWxpZGF0ZUJsb2NrKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIGxhbmd1YWdlLCBtb2R1bGUuZW50cnlQb2ludC5sb2NhdGlvbixcbiAgICB7YWN0aXZlOiBbXSwgb3duZXI6IG1vZHVsZS5lbnRyeVBvaW50LCBvd25lcnM6IGxvb3BPd25lcnN9LCBuZXcgU2V0KCksIG9wdGlvbnMuZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgY29uc3QgZGVjbGFyYXRpb25JZHMgPSBuZXcgU2V0KClcbiAgY29uc3QgZGVjbGFyYXRpb25OYW1lcyA9IG5ldyBTZXQoKVxuICBjb25zdCB0YXJnZXREZWNsYXJhdGlvbk5hbWVzID0gbmV3IFNldCgpXG5cbiAgZm9yIChjb25zdCBmdW5jdGlvbkRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIHtcbiAgICBpZiAoIWZ1bmN0aW9uRGVjbGFyYXRpb24gfHwgdHlwZW9mIGZ1bmN0aW9uRGVjbGFyYXRpb24gIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGZ1bmN0aW9uRGVjbGFyYXRpb24pIHx8XG4gICAgICBmdW5jdGlvbkRlY2xhcmF0aW9uLmtpbmQgIT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIgfHwgIUFycmF5LmlzQXJyYXkoZnVuY3Rpb25EZWNsYXJhdGlvbi5wYXJhbWV0ZXJzKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBmdW5jdGlvbiBkZWNsYXJhdGlvblwiLCBtb2R1bGUubG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlVGFyZ2V0QmluZGluZ0lkZW50aWZpZXIobGFuZ3VhZ2UsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubmFtZSwgXCJmdW5jdGlvblwiLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIGlmIChkZWNsYXJhdGlvbk5hbWVzLmhhcyhmdW5jdGlvbkRlY2xhcmF0aW9uLm5hbWUpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBkdXBsaWNhdGUgZnVuY3Rpb24gJyR7ZnVuY3Rpb25EZWNsYXJhdGlvbi5uYW1lfSdgLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBkZWNsYXJhdGlvbk5hbWVzLmFkZChmdW5jdGlvbkRlY2xhcmF0aW9uLm5hbWUpXG4gICAgY29uc3QgdGFyZ2V0RGVjbGFyYXRpb25OYW1lID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIlxuICAgICAgPyBmdW5jdGlvbkRlY2xhcmF0aW9uLm5hbWUucmVwbGFjZSgvW0EtWl0vZ3UsIChjaGFyYWN0ZXIpID0+IGNoYXJhY3Rlci50b0xvd2VyQ2FzZSgpKVxuICAgICAgOiBmdW5jdGlvbkRlY2xhcmF0aW9uLm5hbWVcblxuICAgIGlmICh0YXJnZXREZWNsYXJhdGlvbk5hbWVzLmhhcyh0YXJnZXREZWNsYXJhdGlvbk5hbWUpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB0YXJnZXQgZnVuY3Rpb24tbmFtZSBjb2xsaXNpb24gJyR7ZnVuY3Rpb25EZWNsYXJhdGlvbi5uYW1lfSdgLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICB0YXJnZXREZWNsYXJhdGlvbk5hbWVzLmFkZCh0YXJnZXREZWNsYXJhdGlvbk5hbWUpXG4gICAgaWYgKHR5cGVvZiBmdW5jdGlvbkRlY2xhcmF0aW9uLmlkICE9IFwic3RyaW5nXCIgfHwgIS9eKD86W2Etel1bYS16MC05Ll8tXSojKT9mdW5jdGlvbjpbMC05XSskL3UudGVzdChmdW5jdGlvbkRlY2xhcmF0aW9uLmlkKSB8fFxuICAgICAgZGVjbGFyYXRpb25JZHMuaGFzKGZ1bmN0aW9uRGVjbGFyYXRpb24uaWQpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiZHVwbGljYXRlIG9yIGludmFsaWQgZnVuY3Rpb24gZGVjbGFyYXRpb24gaWRlbnRpdHlcIiwgZnVuY3Rpb25EZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgZGVjbGFyYXRpb25JZHMuYWRkKGZ1bmN0aW9uRGVjbGFyYXRpb24uaWQpXG4gICAgdmFsaWRhdGVUeXBlUGFyYW1ldGVyVGFyZ2V0cyhmdW5jdGlvbkRlY2xhcmF0aW9uLCBsYW5ndWFnZSlcblxuICAgIGlmICghdGFzazAwNUxhbmd1YWdlcy5oYXMobGFuZ3VhZ2UpICYmIGZ1bmN0aW9uRGVjbGFyYXRpb24ucGFyYW1ldGVycy5sZW5ndGggIT0gMikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImZ1bmN0aW9uIHBhcmFtZXRlciBjb3VudCBvdGhlciB0aGFuIHR3b1wiLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoIXRhc2swMDVMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSAmJiBmdW5jdGlvbkRlY2xhcmF0aW9uLnJldHVyblR5cGU/LmtpbmQgPT0gXCJUeXBlUmVmZXJlbmNlXCIgJiZcbiAgICAgIGZ1bmN0aW9uRGVjbGFyYXRpb24ucmV0dXJuVHlwZS5uYW1lID09IFwidm9pZFwiKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMDUgdm9pZCBmdW5jdGlvbiByZXR1cm5cIiwgZnVuY3Rpb25EZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVCbG9jayhmdW5jdGlvbkRlY2xhcmF0aW9uLmJvZHksIGxhbmd1YWdlLCBmdW5jdGlvbkRlY2xhcmF0aW9uLmxvY2F0aW9uLFxuICAgICAge2FjdGl2ZTogW10sIG93bmVyOiBmdW5jdGlvbkRlY2xhcmF0aW9uLCBvd25lcnM6IGxvb3BPd25lcnN9LCBuZXcgU2V0KCksIG9wdGlvbnMuZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcblxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIGZ1bmN0aW9uRGVjbGFyYXRpb24ucGFyYW1ldGVycykge1xuICAgICAgaWYgKCFwYXJhbWV0ZXIgfHwgdHlwZW9mIHBhcmFtZXRlciAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocGFyYW1ldGVyKSB8fCBwYXJhbWV0ZXIua2luZCAhPSBcIlBhcmFtZXRlclwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgcGFyYW1ldGVyXCIsIGZ1bmN0aW9uRGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgICB9XG4gICAgICB2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyKGxhbmd1YWdlLCBwYXJhbWV0ZXIubmFtZSwgXCJwYXJhbWV0ZXJcIiwgcGFyYW1ldGVyLmxvY2F0aW9uKVxuICAgIH1cbiAgfVxuICB2YWxpZGF0ZUVycm9yVGFyZ2V0cyhlcnJvcnMsIHJlY29yZHMsIG1vZHVsZS5mdW5jdGlvbnMsIGxhbmd1YWdlLCBtb2R1bGUubG9jYXRpb24pXG4gIHZhbGlkYXRlU2NhZmZvbGRpbmdOYW1lcyhtb2R1bGUsIGxhbmd1YWdlKVxuICB2YWxpZGF0ZUJhY2tlbmRUeXBlcyhtb2R1bGUsIGxhbmd1YWdlLCB7XG4gICAgY2FsbEVmZmVjdHM6IG9wdGlvbnMudmlzaWJsZUNhbGxFZmZlY3RzLFxuICAgIGNsYXNzZXM6IG9wdGlvbnMudmlzaWJsZUNsYXNzZXMsXG4gICAgZXJyb3JzOiBvcHRpb25zLnZpc2libGVFcnJvcnMsXG4gICAgZnVuY3Rpb25zOiBvcHRpb25zLnZpc2libGVGdW5jdGlvbnMsXG4gICAgcmVjb3Jkczogb3B0aW9ucy52aXNpYmxlUmVjb3Jkc1xuICB9KVxufVxuXG4vKipcbiAqIFJlamVjdHMgVGFzayAwMTQgSVIgdHJhbnNhY3Rpb25hbGx5IGJlZm9yZSBhIG5vbi1jb2hvcnQgdGFyZ2V0IGFsbG9jYXRlcyBvdXRwdXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBDYW5kaWRhdGUgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGlkZW50aXR5LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlamVjdE9yZGVyZWRNYXBDYXBhYmlsaXR5KG1vZHVsZSwgbGFuZ3VhZ2UpIHtcbiAgY29uc3Qgbm9kZSA9IGZpbmRPcmRlcmVkTWFwTm9kZShtb2R1bGUpXG5cbiAgaWYgKG5vZGUpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAxNCBvcmRlcmVkLW1hcCBpdGVyYXRpb25cIiwgZGlhZ25vc3RpY0xvY2F0aW9uKG5vZGUubG9jYXRpb24sIG1vZHVsZS5sb2NhdGlvbikpXG59XG5cbi8qKlxuICogRmluZHMgdGhlIGZpcnN0IGRpc3RpbmN0IG9yZGVyZWQtbWFwIHR5cGUsIGxpdGVyYWwsIG9yIGxvb3AgaW4gcGFyc2VyLW5ldXRyYWwgSVIuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQ2FuZGlkYXRlIHN1YnRyZWUuXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBDeWNsZSBwcm90ZWN0aW9uLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIHVua25vd24+IHwgdW5kZWZpbmVkfSBGaXJzdCBUYXNrIDAxNCBub2RlLlxuICovXG5mdW5jdGlvbiBmaW5kT3JkZXJlZE1hcE5vZGUodmFsdWUsIHNlZW4gPSBuZXcgU2V0KCkpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIHJldHVybiB1bmRlZmluZWRcbiAgc2Vlbi5hZGQodmFsdWUpXG4gIGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAodmFsdWUpXG5cbiAgICBpZiAoW1wiT3JkZXJlZE1hcFR5cGVcIiwgXCJPcmRlcmVkTWFwTGl0ZXJhbFwiLCBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIl0uaW5jbHVkZXMoU3RyaW5nKGNhbmRpZGF0ZS5raW5kKSkpIHJldHVybiBjYW5kaWRhdGVcbiAgfVxuICBmb3IgKGNvbnN0IGNoaWxkIG9mIEFycmF5LmlzQXJyYXkodmFsdWUpID8gdmFsdWUgOiBPYmplY3QudmFsdWVzKHZhbHVlKSkge1xuICAgIGNvbnN0IGZvdW5kID0gZmluZE9yZGVyZWRNYXBOb2RlKGNoaWxkLCBzZWVuKVxuXG4gICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBSZWplY3RzIHR5cGVkIGVycm9ycyBmb3IgYSB0YXJnZXQgb3V0c2lkZSB0aGUgVGFzayAwMTEgY29ob3J0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gQ2FuZGlkYXRlIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZWplY3RUeXBlZEVycm9ycygvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSAqLyBtb2R1bGUsXG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSAqLyBsYW5ndWFnZSkge1xuICBpZiAoKG1vZHVsZS5lcnJvcnMgPz8gW10pLmxlbmd0aCA+IDApIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMTEgdHlwZWQgZXJyb3JzIGFuZCBoYW5kbGluZ1wiLCBtb2R1bGUuZXJyb3JzPy5bMF0/LmxvY2F0aW9uID8/IG1vZHVsZS5sb2NhdGlvbilcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIHJlamVjdFR5cGVkRXJyb3JCbG9jayhkZWNsYXJhdGlvbj8uYm9keSwgbGFuZ3VhZ2UpXG4gIHJlamVjdFR5cGVkRXJyb3JCbG9jayhtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBsYW5ndWFnZSlcbn1cblxuLyoqXG4gKiBGaW5kcyB0eXBlZC1lcnJvciBzdGF0ZW1lbnRzIHdpdGhvdXQgZGVzY2VuZGluZyB0aHJvdWdoIG1hbGZvcm1lZCBvciBjeWNsaWMgYmxvY2tzLlxuICogQHBhcmFtIHt1bmtub3dufSBibG9jayAtIENhbmRpZGF0ZSBibG9jay5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFtzZWVuXSAtIFZpc2l0ZWQgYmxvY2tzLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlamVjdFR5cGVkRXJyb3JCbG9jaygvKiogQHR5cGUge3Vua25vd259ICovIGJsb2NrLFxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJhY2tlbmRMYW5ndWFnZX0gKi8gbGFuZ3VhZ2UsXG4gIC8qKiBAdHlwZSB7U2V0PG9iamVjdD59ICovIHNlZW4gPSBuZXcgU2V0KCkpIHtcbiAgaWYgKCFibG9jayB8fCB0eXBlb2YgYmxvY2sgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGJsb2NrKSB8fCBzZWVuLmhhcyhibG9jaykpIHJldHVyblxuICBzZWVuLmFkZChibG9jaylcbiAgY29uc3Qgc3RhdGVtZW50cyA9IFJlZmxlY3QuZ2V0KGJsb2NrLCBcInN0YXRlbWVudHNcIilcblxuICBpZiAoIUFycmF5LmlzQXJyYXkoc3RhdGVtZW50cykpIHJldHVyblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBzdGF0ZW1lbnRzKSB7XG4gICAgaWYgKCFzdGF0ZW1lbnQgfHwgdHlwZW9mIHN0YXRlbWVudCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoc3RhdGVtZW50KSkgY29udGludWVcbiAgICBpZiAoUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImtpbmRcIikgPT0gXCJSYWlzZVN0YXRlbWVudFwiIHx8IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJraW5kXCIpID09IFwiVHJ5U3RhdGVtZW50XCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAxMSB0eXBlZCBlcnJvcnMgYW5kIGhhbmRsaW5nXCIsXG4gICAgICAgIGRpYWdub3N0aWNMb2NhdGlvbihSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwibG9jYXRpb25cIiksIFJlZmxlY3QuZ2V0KGJsb2NrLCBcImxvY2F0aW9uXCIpKSlcbiAgICB9XG4gICAgaWYgKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJraW5kXCIpID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgcmVqZWN0VHlwZWRFcnJvckJsb2NrKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJjb25zZXF1ZW50XCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICAgIHJlamVjdFR5cGVkRXJyb3JCbG9jayhSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiYWx0ZXJuYXRlXCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICB9IGVsc2UgaWYgKFtcIkZvckVhY2hTdGF0ZW1lbnRcIiwgXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIsIFwiV2hpbGVTdGF0ZW1lbnRcIl0uaW5jbHVkZXMoU3RyaW5nKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJraW5kXCIpKSkpIHtcbiAgICAgIHJlamVjdFR5cGVkRXJyb3JCbG9jayhSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiYm9keVwiKSwgbGFuZ3VhZ2UsIHNlZW4pXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRhcmdldC12aXNpYmxlIG5vbWluYWwgZXJyb3IgZGVjbGFyYXRpb25zIGJlZm9yZSBlbWlzc2lvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbltdfSBlcnJvcnMgLSBFcnJvciBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uW119IHJlY29yZHMgLSBSZWNvcmQgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uW119IGZ1bmN0aW9ucyAtIEZ1bmN0aW9uIGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IG1vZHVsZUxvY2F0aW9uIC0gTW9kdWxlIGxvY2F0aW9uLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlRXJyb3JUYXJnZXRzKFxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb25bXX0gKi8gZXJyb3JzLFxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uW119ICovIHJlY29yZHMsXG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbltdfSAqLyBmdW5jdGlvbnMsXG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSAqLyBsYW5ndWFnZSxcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gKi8gbW9kdWxlTG9jYXRpb25cbikge1xuICBjb25zdCBpZHMgPSBuZXcgU2V0KClcbiAgY29uc3QgbmFtZXMgPSBuZXcgU2V0KFsuLi5yZWNvcmRzLCAuLi5mdW5jdGlvbnNdLm1hcCgoe25hbWV9KSA9PiBsYW5ndWFnZSA9PSBcInBocFwiID8gbmFtZS50b0xvd2VyQ2FzZSgpIDogbmFtZSkpXG4gIGNvbnN0IGZvcmJpZGRlbiA9IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiID8gbmV3IFNldChbXCJFcnJvclwiLCBcIkFnZ3JlZ2F0ZUVycm9yXCJdKSA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IG5ldyBTZXQoW1wiVGhyb3dhYmxlXCIsIFwiRXhjZXB0aW9uXCIsIFwiUnVudGltZUV4Y2VwdGlvblwiLCBcIkVycm9yXCJdKSA6XG4gICAgICBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IG5ldyBTZXQoW1wiRXhjZXB0aW9uXCIsIFwiU3RhbmRhcmRFcnJvclwiLCBcIlNjcmlwdEVycm9yXCIsIFwiU3lzdGVtRXhpdFwiXSkgOlxuICAgICAgICBsYW5ndWFnZSA9PSBcImphdmFcIiA/IG5ldyBTZXQoW1wiVGhyb3dhYmxlXCIsIFwiRXhjZXB0aW9uXCIsIFwiUnVudGltZUV4Y2VwdGlvblwiLCBcIkVycm9yXCJdKSA6IG5ldyBTZXQoKVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBlcnJvcnMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSBlcnJvcnNbaW5kZXhdXG4gICAgY29uc3QgbG9jYXRpb24gPSBkaWFnbm9zdGljTG9jYXRpb24oZGVjbGFyYXRpb24/LmxvY2F0aW9uLCBtb2R1bGVMb2NhdGlvbilcbiAgICBjb25zdCBmaWVsZHMgPSBkZWNsYXJhdGlvbiAmJiB0eXBlb2YgZGVjbGFyYXRpb24gPT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbilcbiAgICAgID8gT2JqZWN0LmtleXMoZGVjbGFyYXRpb24pLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSA6IFwiXCJcblxuICAgIGlmICghZGVjbGFyYXRpb24gfHwgdHlwZW9mIGRlY2xhcmF0aW9uICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbikgfHxcbiAgICAgIGRlY2xhcmF0aW9uLmtpbmQgIT0gXCJFcnJvckRlY2xhcmF0aW9uXCIgfHwgZmllbGRzICE9IFwiaWQsa2luZCxsb2NhdGlvbixuYW1lXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgZXJyb3IgZGVjbGFyYXRpb25cIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKGRlY2xhcmF0aW9uLmxvY2F0aW9uLCBsYW5ndWFnZSwgXCJlcnJvciBkZWNsYXJhdGlvbiBsb2NhdGlvblwiLCBtb2R1bGVMb2NhdGlvbilcbiAgICB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyKGxhbmd1YWdlLCBkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICBpZiAoKGRlY2xhcmF0aW9uLmlkICE9IGBlcnJvcjoke2luZGV4fWAgJiZcbiAgICAgICFuZXcgUmVnRXhwKGBeW2Etel1bYS16MC05Ll8tXSojZXJyb3I6JHtpbmRleH0kYCwgXCJ1XCIpLnRlc3QoZGVjbGFyYXRpb24uaWQgPz8gXCJcIikpIHx8IGlkcy5oYXMoZGVjbGFyYXRpb24uaWQpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiZHVwbGljYXRlIG9yIGludmFsaWQgZXJyb3IgZGVjbGFyYXRpb24gaWRlbnRpdHlcIiwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSBsYW5ndWFnZSA9PSBcInBocFwiID8gZGVjbGFyYXRpb24ubmFtZS50b0xvd2VyQ2FzZSgpIDogZGVjbGFyYXRpb24ubmFtZVxuXG4gICAgaWYgKG5hbWVzLmhhcyhub3JtYWxpemVkKSB8fCBmb3JiaWRkZW4uaGFzKGRlY2xhcmF0aW9uLm5hbWUpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBlcnJvciBkZWNsYXJhdGlvbiBjb2xsaXNpb24gJyR7ZGVjbGFyYXRpb24ubmFtZX0nYCwgZGVjbGFyYXRpb24ubG9jYXRpb24pXG4gICAgfVxuICAgIGlkcy5hZGQoZGVjbGFyYXRpb24uaWQpXG4gICAgbmFtZXMuYWRkKG5vcm1hbGl6ZWQpXG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgZXZlcnkgbm9taW5hbCByZWNvcmQgaWRlbnRpZmllciwgaWRlbnRpdHksIGZpZWxkLCBhbmQgdGFyZ2V0IGNvbGxpc2lvbiBiZWZvcmUgb3V0cHV0IGFsbG9jYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uW119IHJlY29yZHMgLSBDYW5kaWRhdGUgcmVjb3Jkcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbltdfSBmdW5jdGlvbnMgLSBDYW5kaWRhdGUgZnVuY3Rpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGxhbmd1YWdlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiB8IHVuZGVmaW5lZH0gbW9kdWxlTG9jYXRpb24gLSBNb2R1bGUgZmFsbGJhY2sgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVSZWNvcmRUYXJnZXRzKHJlY29yZHMsIGZ1bmN0aW9ucywgbGFuZ3VhZ2UsIG1vZHVsZUxvY2F0aW9uKSB7XG4gIGNvbnN0IGRlY2xhcmF0aW9uSWRzID0gbmV3IFNldCgpXG4gIGNvbnN0IHRhcmdldE5hbWVzID0gbmV3IFNldCgpXG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBmdW5jdGlvbnMpIHtcbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24pKSBjb250aW51ZVxuICAgIGNvbnN0IG5hbWUgPSBSZWZsZWN0LmdldChkZWNsYXJhdGlvbiwgXCJuYW1lXCIpXG5cbiAgICBpZiAodHlwZW9mIG5hbWUgIT0gXCJzdHJpbmdcIikgY29udGludWVcbiAgICB0YXJnZXROYW1lcy5hZGQobGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IG5hbWUudG9Mb3dlckNhc2UoKSA6IG5hbWUpXG4gIH1cblxuICBmb3IgKGxldCByZWNvcmRJbmRleCA9IDA7IHJlY29yZEluZGV4IDwgcmVjb3Jkcy5sZW5ndGg7IHJlY29yZEluZGV4ICs9IDEpIHtcbiAgICBjb25zdCByZWNvcmQgPSByZWNvcmRzW3JlY29yZEluZGV4XVxuICAgIGNvbnN0IGxvY2F0aW9uID0gZGlhZ25vc3RpY0xvY2F0aW9uKHJlY29yZD8ubG9jYXRpb24sIG1vZHVsZUxvY2F0aW9uKVxuICAgIGNvbnN0IHJlY29yZEtleXMgPSByZWNvcmQgJiYgdHlwZW9mIHJlY29yZCA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHJlY29yZClcbiAgICAgID8gT2JqZWN0LmtleXMocmVjb3JkKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIilcbiAgICAgIDogXCJcIlxuXG4gICAgaWYgKCFyZWNvcmQgfHwgdHlwZW9mIHJlY29yZCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocmVjb3JkKSB8fCByZWNvcmQua2luZCAhPSBcIlJlY29yZERlY2xhcmF0aW9uXCIgfHxcbiAgICAgICFbXCJmaWVsZHMsaWQsa2luZCxsb2NhdGlvbixuYW1lXCIsIFwiZmllbGRzLGlkLGtpbmQsbG9jYXRpb24sbmFtZSx0eXBlUGFyYW1ldGVyc1wiXS5pbmNsdWRlcyhyZWNvcmRLZXlzKSB8fCAhaXNEZW5zZUFycmF5KHJlY29yZC5maWVsZHMpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIHJlY29yZCBkZWNsYXJhdGlvblwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgcmVxdWlyZVNlbWFudGljTG9jYXRpb24ocmVjb3JkLmxvY2F0aW9uLCBsYW5ndWFnZSwgXCJyZWNvcmQgZGVjbGFyYXRpb24gbG9jYXRpb25cIiwgbW9kdWxlTG9jYXRpb24pXG4gICAgdmFsaWRhdGVUYXJnZXRUeXBlSWRlbnRpZmllcihsYW5ndWFnZSwgcmVjb3JkLm5hbWUsIHJlY29yZC5sb2NhdGlvbilcbiAgICBpZiAodHlwZW9mIHJlY29yZC5pZCAhPSBcInN0cmluZ1wiIHx8ICFuZXcgUmVnRXhwKGBeKD86W2Etel1bYS16MC05Ll8tXSojKT9yZWNvcmQ6JHtyZWNvcmRJbmRleH0kYCwgXCJ1XCIpLnRlc3QocmVjb3JkLmlkKSB8fFxuICAgICAgZGVjbGFyYXRpb25JZHMuaGFzKHJlY29yZC5pZCkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJkdXBsaWNhdGUgb3IgaW52YWxpZCByZWNvcmQgZGVjbGFyYXRpb24gaWRlbnRpdHlcIiwgcmVjb3JkLmxvY2F0aW9uKVxuICAgIH1cbiAgICBkZWNsYXJhdGlvbklkcy5hZGQocmVjb3JkLmlkKVxuICAgIHZhbGlkYXRlVHlwZVBhcmFtZXRlclRhcmdldHMocmVjb3JkLCBsYW5ndWFnZSlcbiAgICBjb25zdCB0YXJnZXROYW1lID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IHJlY29yZC5uYW1lLnRvTG93ZXJDYXNlKCkgOiByZWNvcmQubmFtZVxuXG4gICAgaWYgKHRhcmdldE5hbWVzLmhhcyh0YXJnZXROYW1lKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgcmVjb3JkIGRlY2xhcmF0aW9uIGNvbGxpc2lvbiAnJHtyZWNvcmQubmFtZX0nYCwgcmVjb3JkLmxvY2F0aW9uKVxuICAgIHRhcmdldE5hbWVzLmFkZCh0YXJnZXROYW1lKVxuICAgIGNvbnN0IGZpZWxkTmFtZXMgPSBuZXcgU2V0KClcblxuICAgIGZvciAobGV0IGZpZWxkSW5kZXggPSAwOyBmaWVsZEluZGV4IDwgcmVjb3JkLmZpZWxkcy5sZW5ndGg7IGZpZWxkSW5kZXggKz0gMSkge1xuICAgICAgY29uc3QgZmllbGQgPSByZWNvcmQuZmllbGRzW2ZpZWxkSW5kZXhdXG4gICAgICBjb25zdCBmaWVsZExvY2F0aW9uID0gZGlhZ25vc3RpY0xvY2F0aW9uKGZpZWxkPy5sb2NhdGlvbiwgcmVjb3JkLmxvY2F0aW9uKVxuICAgICAgY29uc3QgZmllbGRLZXlzID0gZmllbGQgJiYgdHlwZW9mIGZpZWxkID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZmllbGQpXG4gICAgICAgID8gT2JqZWN0LmtleXMoZmllbGQpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuICAgICAgICA6IFwiXCJcblxuICAgICAgaWYgKCFmaWVsZCB8fCB0eXBlb2YgZmllbGQgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGZpZWxkKSB8fCBmaWVsZC5raW5kICE9IFwiUmVjb3JkRmllbGRcIiB8fFxuICAgICAgICBmaWVsZEtleXMgIT0gXCJpZCxraW5kLGxvY2F0aW9uLG5hbWUsdHlwZVwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgcmVjb3JkIGZpZWxkXCIsIGZpZWxkTG9jYXRpb24pXG4gICAgICB9XG4gICAgICByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihmaWVsZC5sb2NhdGlvbiwgbGFuZ3VhZ2UsIFwicmVjb3JkIGZpZWxkIGxvY2F0aW9uXCIsIHJlY29yZC5sb2NhdGlvbilcbiAgICAgIGlmIChmaWVsZC5pZCAhPSBgJHtyZWNvcmQuaWR9OmZpZWxkOiR7ZmllbGRJbmRleH1gKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJkdXBsaWNhdGUgb3IgaW52YWxpZCByZWNvcmQgZmllbGQgaWRlbnRpdHlcIiwgZmllbGQubG9jYXRpb24pXG4gICAgICB9XG4gICAgICB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIGZpZWxkLm5hbWUsIFwicmVjb3JkIGZpZWxkXCIsIGZpZWxkLmxvY2F0aW9uKVxuICAgICAgY29uc3QgY29sbGlzaW9uID0gbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgJiYgW1wiY29uc3RydWN0b3JcIiwgXCJwcm90b3R5cGVcIiwgXCJfX3Byb3RvX19cIl0uaW5jbHVkZXMoZmllbGQubmFtZSkgfHxcbiAgICAgICAgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgJiYgW1wiY29uc3RydWN0b3JcIiwgXCJwcm90b3R5cGVcIiwgXCJfX3Byb3RvX19cIl0uaW5jbHVkZXMoZmllbGQubmFtZSkgfHxcbiAgICAgICAgbGFuZ3VhZ2UgPT0gXCJwaHBcIiAmJiBmaWVsZC5uYW1lLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChcIl9fXCIpIHx8XG4gICAgICAgIGxhbmd1YWdlID09IFwicnVieVwiICYmIFtcImluaXRpYWxpemVcIiwgXCJmcmVlemVcIiwgXCJzZW5kXCIsIFwicHVibGljX3NlbmRcIiwgXCJtZXRob2RcIiwgXCJzaW5nbGV0b25fY2xhc3NcIl0uaW5jbHVkZXMoZmllbGQubmFtZSkgfHxcbiAgICAgICAgbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgJiYgamF2YU9iamVjdEluc3RhbmNlTWV0aG9kU2lnbmF0dXJlcy5oYXMoYCR7ZmllbGQubmFtZX0oKWApXG5cbiAgICAgIGlmIChjb2xsaXNpb24pIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYHJlY29yZCBmaWVsZCBjb2xsaXNpb24gJyR7ZmllbGQubmFtZX0nYCwgZmllbGQubG9jYXRpb24pXG4gICAgICBjb25zdCBub3JtYWxpemVkID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IGZpZWxkLm5hbWUudG9Mb3dlckNhc2UoKSA6IGZpZWxkLm5hbWVcblxuICAgICAgaWYgKGZpZWxkTmFtZXMuaGFzKG5vcm1hbGl6ZWQpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBkdXBsaWNhdGUgdGFyZ2V0IHJlY29yZCBmaWVsZCAnJHtmaWVsZC5uYW1lfSdgLCBmaWVsZC5sb2NhdGlvbilcbiAgICAgIGZpZWxkTmFtZXMuYWRkKG5vcm1hbGl6ZWQpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBleGFjdCB0YXJnZXQtdmlzaWJsZSBzaGFwZSBvZiBldmVyeSByZWZlcmVuY2UgY2xhc3MgYmVmb3JlIG91dHB1dCBhbGxvY2F0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uW119IGNsYXNzZXMgLSBDYW5kaWRhdGUgY2xhc3Nlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb25bXX0gcmVjb3JkcyAtIEV4aXN0aW5nIHJlY29yZHMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb25bXX0gZXJyb3JzIC0gRXhpc3RpbmcgdHlwZWQgZXJyb3JzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uW119IGZ1bmN0aW9ucyAtIEV4aXN0aW5nIGZ1bmN0aW9ucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9IG1vZHVsZUxvY2F0aW9uIC0gRmFsbGJhY2sgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVSZWZlcmVuY2VDbGFzc1RhcmdldHMoY2xhc3NlcywgcmVjb3JkcywgZXJyb3JzLCBmdW5jdGlvbnMsIGxhbmd1YWdlLCBtb2R1bGVMb2NhdGlvbikge1xuICBjb25zdCB0YXJnZXROYW1lcyA9IG5ldyBTZXQoKVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgWy4uLnJlY29yZHMsIC4uLmVycm9ycywgLi4uZnVuY3Rpb25zXSkge1xuICAgIGlmICghZGVjbGFyYXRpb24gfHwgdHlwZW9mIGRlY2xhcmF0aW9uICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbikpIGNvbnRpbnVlXG4gICAgY29uc3QgbmFtZSA9IFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcIm5hbWVcIilcblxuICAgIGlmICh0eXBlb2YgbmFtZSAhPSBcInN0cmluZ1wiKSBjb250aW51ZVxuICAgIHRhcmdldE5hbWVzLmFkZChsYW5ndWFnZSA9PSBcInBocFwiID8gbmFtZS50b0xvd2VyQ2FzZSgpIDogbmFtZSlcbiAgfVxuXG4gIGZvciAobGV0IGNsYXNzSW5kZXggPSAwOyBjbGFzc0luZGV4IDwgY2xhc3Nlcy5sZW5ndGg7IGNsYXNzSW5kZXggKz0gMSkge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gY2xhc3Nlc1tjbGFzc0luZGV4XVxuICAgIGNvbnN0IGxvY2F0aW9uID0gZGlhZ25vc3RpY0xvY2F0aW9uKGRlY2xhcmF0aW9uPy5sb2NhdGlvbiwgbW9kdWxlTG9jYXRpb24pXG4gICAgY29uc3Qga2V5cyA9IGRlY2xhcmF0aW9uICYmIHR5cGVvZiBkZWNsYXJhdGlvbiA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGRlY2xhcmF0aW9uKVxuICAgICAgPyBPYmplY3Qua2V5cyhkZWNsYXJhdGlvbikuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpIDogXCJcIlxuXG4gICAgaWYgKCFkZWNsYXJhdGlvbiB8fCBkZWNsYXJhdGlvbi5raW5kICE9IFwiQ2xhc3NEZWNsYXJhdGlvblwiIHx8XG4gICAgICAhW1wiY29uc3RydWN0b3IsZmllbGRzLGlkLGtpbmQsbG9jYXRpb24sbWV0aG9kcyxuYW1lXCIsIFwiY29uc3RydWN0b3IsZmllbGRzLGlkLGtpbmQsbG9jYXRpb24sbWV0aG9kcyxuYW1lLG93bmVyc2hpcFwiXS5pbmNsdWRlcyhrZXlzKSB8fFxuICAgICAgIWlzRGVuc2VBcnJheShkZWNsYXJhdGlvbi5maWVsZHMpIHx8IGRlY2xhcmF0aW9uLmZpZWxkcy5sZW5ndGggPT0gMCB8fCAhaXNEZW5zZUFycmF5KGRlY2xhcmF0aW9uLm1ldGhvZHMpIHx8XG4gICAgICAhbmV3IFJlZ0V4cChgXig/OlthLXpdW2EtejAtOS5fLV0qIyk/Y2xhc3M6JHtjbGFzc0luZGV4fSRgLCBcInVcIikudGVzdChTdHJpbmcoZGVjbGFyYXRpb24uaWQpKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCByZWZlcmVuY2UgY2xhc3MgZGVjbGFyYXRpb25cIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChkZWNsYXJhdGlvbi5vd25lcnNoaXAgIT09IHVuZGVmaW5lZCAmJiBkZWNsYXJhdGlvbi5vd25lcnNoaXA/LmtpbmQgIT0gXCJvcmRpbmFyeVwiICYmXG4gICAgICAoZGVjbGFyYXRpb24ub3duZXJzaGlwPy5raW5kICE9IFwib3duZWRSZXNvdXJjZVwiIHx8IHR5cGVvZiBkZWNsYXJhdGlvbi5vd25lcnNoaXAuZmllbGRJZCAhPSBcInN0cmluZ1wiIHx8XG4gICAgICB0eXBlb2YgZGVjbGFyYXRpb24ub3duZXJzaGlwLnJlc291cmNlSWQgIT0gXCJzdHJpbmdcIikpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgcmVmZXJlbmNlIGNsYXNzIHJlc291cmNlIG93bmVyc2hpcFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgZGVjbGFyYXRpb25Mb2NhdGlvbiA9IHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKGRlY2xhcmF0aW9uLmxvY2F0aW9uLCBsYW5ndWFnZSwgXCJyZWZlcmVuY2UgY2xhc3MgZGVjbGFyYXRpb24gbG9jYXRpb25cIiwgbW9kdWxlTG9jYXRpb24pXG5cbiAgICB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyKGxhbmd1YWdlLCBkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbkxvY2F0aW9uKVxuICAgIGNvbnN0IHRhcmdldE5hbWUgPSBsYW5ndWFnZSA9PSBcInBocFwiID8gZGVjbGFyYXRpb24ubmFtZS50b0xvd2VyQ2FzZSgpIDogZGVjbGFyYXRpb24ubmFtZVxuXG4gICAgaWYgKHRhcmdldE5hbWVzLmhhcyh0YXJnZXROYW1lKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgcmVmZXJlbmNlIGNsYXNzIGNvbGxpc2lvbiAnJHtkZWNsYXJhdGlvbi5uYW1lfSdgLCBkZWNsYXJhdGlvbkxvY2F0aW9uKVxuICAgIHRhcmdldE5hbWVzLmFkZCh0YXJnZXROYW1lKVxuICAgIGNvbnN0IGZpZWxkTmFtZXMgPSBuZXcgU2V0KClcblxuICAgIGZvciAobGV0IGZpZWxkSW5kZXggPSAwOyBmaWVsZEluZGV4IDwgZGVjbGFyYXRpb24uZmllbGRzLmxlbmd0aDsgZmllbGRJbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IGRlY2xhcmF0aW9uLmZpZWxkc1tmaWVsZEluZGV4XVxuICAgICAgY29uc3QgZmllbGRMb2NhdGlvbiA9IGRpYWdub3N0aWNMb2NhdGlvbihmaWVsZD8ubG9jYXRpb24sIGxvY2F0aW9uKVxuICAgICAgY29uc3QgZmllbGRLZXlzID0gZmllbGQgJiYgdHlwZW9mIGZpZWxkID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZmllbGQpXG4gICAgICAgID8gT2JqZWN0LmtleXMoZmllbGQpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSA6IFwiXCJcblxuICAgICAgaWYgKCFmaWVsZCB8fCBmaWVsZC5raW5kICE9IFwiUHJpdmF0ZUZpZWxkXCIgfHwgZmllbGRLZXlzICE9IFwiaWQsa2luZCxsb2NhdGlvbixuYW1lLHR5cGVcIiB8fFxuICAgICAgICBmaWVsZC5pZCAhPSBgJHtkZWNsYXJhdGlvbi5pZH06ZmllbGQ6JHtmaWVsZEluZGV4fWApIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBwcml2YXRlIGZpZWxkXCIsIGZpZWxkTG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCBleGFjdEZpZWxkTG9jYXRpb24gPSByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihmaWVsZC5sb2NhdGlvbiwgbGFuZ3VhZ2UsIFwicHJpdmF0ZSBmaWVsZCBsb2NhdGlvblwiLCBkZWNsYXJhdGlvbkxvY2F0aW9uKVxuXG4gICAgICB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIGZpZWxkLm5hbWUsIFwicHJpdmF0ZSBmaWVsZFwiLCBleGFjdEZpZWxkTG9jYXRpb24pXG4gICAgICBjb25zdCBub3JtYWxpemVkID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IGZpZWxkLm5hbWUudG9Mb3dlckNhc2UoKSA6IGZpZWxkLm5hbWVcblxuICAgICAgaWYgKGZpZWxkTmFtZXMuaGFzKG5vcm1hbGl6ZWQpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBkdXBsaWNhdGUgdGFyZ2V0IHByaXZhdGUgZmllbGQgJyR7ZmllbGQubmFtZX0nYCwgZXhhY3RGaWVsZExvY2F0aW9uKVxuICAgICAgZmllbGROYW1lcy5hZGQobm9ybWFsaXplZClcbiAgICB9XG4gICAgY29uc3QgY29uc3RydWN0b3IgPSBkZWNsYXJhdGlvbi5jb25zdHJ1Y3RvclxuICAgIGNvbnN0IGNvbnN0cnVjdG9yTG9jYXRpb24gPSBkaWFnbm9zdGljTG9jYXRpb24oY29uc3RydWN0b3I/LmxvY2F0aW9uLCBsb2NhdGlvbilcbiAgICBjb25zdCBjb25zdHJ1Y3RvcktleXMgPSBjb25zdHJ1Y3RvciAmJiB0eXBlb2YgY29uc3RydWN0b3IgPT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShjb25zdHJ1Y3RvcilcbiAgICAgID8gT2JqZWN0LmtleXMoY29uc3RydWN0b3IpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSA6IFwiXCJcblxuICAgIGlmICghY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3Iua2luZCAhPSBcIkNvbnN0cnVjdG9yRGVjbGFyYXRpb25cIiB8fFxuICAgICAgIVtcImJvZHksaWQsa2luZCxsb2NhdGlvbixwYXJhbWV0ZXJzXCIsIFwiYm9keSxlZmZlY3RzLGZhaWx1cmVJZHMsaWQsa2luZCxsb2NhdGlvbixwYXJhbWV0ZXJzXCJdLmluY2x1ZGVzKGNvbnN0cnVjdG9yS2V5cykgfHxcbiAgICAgIGNvbnN0cnVjdG9yLmlkICE9IGAke2RlY2xhcmF0aW9uLmlkfTpjb25zdHJ1Y3RvcmAgfHwgIWlzRGVuc2VBcnJheShjb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBjb25zdHJ1Y3RvciBkZWNsYXJhdGlvblwiLCBjb25zdHJ1Y3RvckxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBleGFjdENvbnN0cnVjdG9yTG9jYXRpb24gPSByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihjb25zdHJ1Y3Rvci5sb2NhdGlvbiwgbGFuZ3VhZ2UsIFwiY29uc3RydWN0b3IgZGVjbGFyYXRpb24gbG9jYXRpb25cIiwgZGVjbGFyYXRpb25Mb2NhdGlvbilcblxuICAgIHZhbGlkYXRlUmVmZXJlbmNlQ2xhc3NQYXJhbWV0ZXJzKGNvbnN0cnVjdG9yLnBhcmFtZXRlcnMsIFwiY29uc3RydWN0b3JcIiwgbGFuZ3VhZ2UsIGV4YWN0Q29uc3RydWN0b3JMb2NhdGlvbilcbiAgICBjb25zdCBtZXRob2ROYW1lcyA9IG5ldyBTZXQoKVxuXG4gICAgZm9yIChsZXQgbWV0aG9kSW5kZXggPSAwOyBtZXRob2RJbmRleCA8IGRlY2xhcmF0aW9uLm1ldGhvZHMubGVuZ3RoOyBtZXRob2RJbmRleCArPSAxKSB7XG4gICAgICBjb25zdCBtZXRob2QgPSBkZWNsYXJhdGlvbi5tZXRob2RzW21ldGhvZEluZGV4XVxuICAgICAgY29uc3QgbWV0aG9kTG9jYXRpb24gPSBkaWFnbm9zdGljTG9jYXRpb24obWV0aG9kPy5sb2NhdGlvbiwgbG9jYXRpb24pXG4gICAgICBjb25zdCBtZXRob2RLZXlzID0gbWV0aG9kICYmIHR5cGVvZiBtZXRob2QgPT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheShtZXRob2QpXG4gICAgICAgID8gT2JqZWN0LmtleXMobWV0aG9kKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIikgOiBcIlwiXG5cbiAgICAgIGlmICghbWV0aG9kIHx8IG1ldGhvZC5raW5kICE9IFwiTWV0aG9kRGVjbGFyYXRpb25cIiB8fFxuICAgICAgICAhW1wiYm9keSxpZCxraW5kLGxvY2F0aW9uLG5hbWUscGFyYW1ldGVycyxyZXR1cm5UeXBlXCIsXG4gICAgICAgICAgXCJib2R5LGVmZmVjdHMsZmFpbHVyZUlkcyxpZCxraW5kLGxvY2F0aW9uLG5hbWUscGFyYW1ldGVycyxyZXR1cm5UeXBlXCJdLmluY2x1ZGVzKG1ldGhvZEtleXMpIHx8XG4gICAgICAgIG1ldGhvZC5pZCAhPSBgJHtkZWNsYXJhdGlvbi5pZH06bWV0aG9kOiR7bWV0aG9kSW5kZXh9YCB8fCAhaXNEZW5zZUFycmF5KG1ldGhvZC5wYXJhbWV0ZXJzKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIG1ldGhvZCBkZWNsYXJhdGlvblwiLCBtZXRob2RMb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGV4YWN0TWV0aG9kTG9jYXRpb24gPSByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihtZXRob2QubG9jYXRpb24sIGxhbmd1YWdlLCBcIm1ldGhvZCBkZWNsYXJhdGlvbiBsb2NhdGlvblwiLCBkZWNsYXJhdGlvbkxvY2F0aW9uKVxuICAgICAgY29uc3QgbGlmZWN5Y2xlTmFtZSA9IGxhbmd1YWdlID09IFwicGhwXCIgPyBcIl9fY29uc3RydWN0XCIgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IFwiaW5pdGlhbGl6ZVwiIDpcbiAgICAgICAgbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyBcImNvbnN0cnVjdG9yXCIgOiB1bmRlZmluZWRcblxuICAgICAgaWYgKG1ldGhvZC5uYW1lID09IGxpZmVjeWNsZU5hbWUpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgcmVzZXJ2ZWQgcmVmZXJlbmNlIGxpZmVjeWNsZSBtZXRob2QgJyR7bWV0aG9kLm5hbWV9J2AsIGV4YWN0TWV0aG9kTG9jYXRpb24pXG4gICAgICB9XG4gICAgICBjb25zdCByZXNlcnZlZEhvb2sgPSBsYW5ndWFnZSA9PSBcInBocFwiID8gL15fXy91LnRlc3QobWV0aG9kLm5hbWUpIDpcbiAgICAgICAgbGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBydWJ5UmVmZXJlbmNlTWV0aG9kSG9va3MuaGFzKG1ldGhvZC5uYW1lKSB8fFxuICAgICAgICAgIHR5cGVvZiBtZXRob2QubmFtZSA9PSBcInN0cmluZ1wiICYmIG1ldGhvZC5uYW1lLmVuZHNXaXRoKFwiPVwiKSA6XG4gICAgICAgICAgbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBqYXZhUmVmZXJlbmNlTWV0aG9kSG9va3MuaGFzKG1ldGhvZC5uYW1lKSA6XG4gICAgICAgICAgICBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiB8fCBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IGphdmFzY3JpcHRSZWZlcmVuY2VNZXRob2RIb29rcy5oYXMobWV0aG9kLm5hbWUpIDogZmFsc2VcblxuICAgICAgaWYgKHJlc2VydmVkSG9vaykgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgcmVzZXJ2ZWQgcmVmZXJlbmNlIG1ldGhvZCAnJHttZXRob2QubmFtZX0nYCwgZXhhY3RNZXRob2RMb2NhdGlvbilcbiAgICAgIGlmIChsYW5ndWFnZSA9PSBcInJ1YnlcIikge1xuICAgICAgICBpZiAodHlwZW9mIG1ldGhvZC5uYW1lICE9IFwic3RyaW5nXCIgfHwgIS9eW0EtWmEtel9dW0EtWmEtejAtOV9dKlshPz1dPyQvdS50ZXN0KG1ldGhvZC5uYW1lKSkge1xuICAgICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYG1ldGhvZCBpZGVudGlmaWVyICcke1N0cmluZyhtZXRob2QubmFtZSl9J2AsIGV4YWN0TWV0aG9kTG9jYXRpb24pXG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIG1ldGhvZC5uYW1lLCBcIm1ldGhvZFwiLCBleGFjdE1ldGhvZExvY2F0aW9uKVxuICAgICAgY29uc3Qgbm9ybWFsaXplZCA9IGxhbmd1YWdlID09IFwicGhwXCIgPyBtZXRob2QubmFtZS50b0xvd2VyQ2FzZSgpIDogbWV0aG9kLm5hbWVcblxuICAgICAgaWYgKG1ldGhvZE5hbWVzLmhhcyhub3JtYWxpemVkKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgZHVwbGljYXRlIHRhcmdldCBtZXRob2QgJyR7bWV0aG9kLm5hbWV9J2AsIGV4YWN0TWV0aG9kTG9jYXRpb24pXG4gICAgICBpZiAobGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgJiYgZmllbGROYW1lcy5oYXMobm9ybWFsaXplZCkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgdGFyZ2V0IGNsYXNzIG1lbWJlciBjb2xsaXNpb24gJyR7bWV0aG9kLm5hbWV9J2AsIGV4YWN0TWV0aG9kTG9jYXRpb24pXG4gICAgICB9XG4gICAgICBtZXRob2ROYW1lcy5hZGQobm9ybWFsaXplZClcbiAgICAgIHZhbGlkYXRlUmVmZXJlbmNlQ2xhc3NQYXJhbWV0ZXJzKG1ldGhvZC5wYXJhbWV0ZXJzLCBcIm1ldGhvZFwiLCBsYW5ndWFnZSwgZXhhY3RNZXRob2RMb2NhdGlvbilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIHJlZmVyZW5jZSBjYWxsYWJsZSdzIGV4YWN0IHBhcmFtZXRlciBzaGFwZSBhbmQgdGFyZ2V0IG5hbWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QYXJhbWV0ZXJbXX0gcGFyYW1ldGVycyAtIENhbmRpZGF0ZSBwYXJhbWV0ZXJzLlxuICogQHBhcmFtIHtcImNvbnN0cnVjdG9yXCIgfCBcIm1ldGhvZFwifSBvd25lciAtIENhbGxhYmxlIGtpbmQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJhY2tlbmRMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uIHwgdW5kZWZpbmVkfSBvd25lckxvY2F0aW9uIC0gRmFsbGJhY2sgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVSZWZlcmVuY2VDbGFzc1BhcmFtZXRlcnMocGFyYW1ldGVycywgb3duZXIsIGxhbmd1YWdlLCBvd25lckxvY2F0aW9uKSB7XG4gIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIHBhcmFtZXRlcnMpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IGRpYWdub3N0aWNMb2NhdGlvbihwYXJhbWV0ZXI/LmxvY2F0aW9uLCBvd25lckxvY2F0aW9uKVxuICAgIGNvbnN0IGtleXMgPSBwYXJhbWV0ZXIgJiYgdHlwZW9mIHBhcmFtZXRlciA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHBhcmFtZXRlcilcbiAgICAgID8gT2JqZWN0LmtleXMocGFyYW1ldGVyKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIikgOiBcIlwiXG5cbiAgICBpZiAoIXBhcmFtZXRlciB8fCBwYXJhbWV0ZXIua2luZCAhPSBcIlBhcmFtZXRlclwiIHx8IGtleXMgIT0gXCJraW5kLGxvY2F0aW9uLG5hbWUsdHlwZVwiKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBtaXNzaW5nIG9yIGludmFsaWQgJHtvd25lcn0gcGFyYW1ldGVyYCwgbG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IGV4YWN0TG9jYXRpb24gPSByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihwYXJhbWV0ZXIubG9jYXRpb24sIGxhbmd1YWdlLCBgJHtvd25lcn0gcGFyYW1ldGVyIGxvY2F0aW9uYCwgb3duZXJMb2NhdGlvbilcblxuICAgIHZhbGlkYXRlVGFyZ2V0QmluZGluZ0lkZW50aWZpZXIobGFuZ3VhZ2UsIHBhcmFtZXRlci5uYW1lLCBcInBhcmFtZXRlclwiLCBleGFjdExvY2F0aW9uKVxuICB9XG59XG5cbi8qKlxuICogVmFsaWRhdGVzIG9uZSBkZWNsYXJhdGlvbidzIHRhcmdldC12aXNpYmxlIHR5cGUtcGFyYW1ldGVyIG5hbWVzIGFuZCBpZGVudGl0aWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gT3duZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJhY2tlbmRMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVUeXBlUGFyYW1ldGVyVGFyZ2V0cyhkZWNsYXJhdGlvbiwgbGFuZ3VhZ2UpIHtcbiAgaWYgKGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzID09PSB1bmRlZmluZWQpIHJldHVyblxuICBpZiAoIWlzRGVuc2VBcnJheShkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycykpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIHR5cGUgcGFyYW1ldGVyIGRlY2xhcmF0aW9uc1wiLCBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgfVxuICBjb25zdCBuYW1lcyA9IG5ldyBTZXQoKVxuICAvKipcbiAgICogTm9ybWFsaXplcyBhIHR5cGUvdmFsdWUgc3BlbGxpbmcgZm9yIHRhcmdldCBjb2xsaXNpb24gY2hlY2tzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIENhbmRpZGF0ZSB0YXJnZXQgbmFtZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gVGFyZ2V0IGNvbXBhcmlzb24ga2V5LlxuICAgKi9cbiAgY29uc3QgdGFyZ2V0S2V5ID0gKG5hbWUpID0+IGxhbmd1YWdlID09IFwicGhwXCIgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOiBuYW1lXG4gIGNvbnN0IHZhbHVlTmFtZXMgPSBuZXcgU2V0KFtcbiAgICBkZWNsYXJhdGlvbi5uYW1lLFxuICAgIC4uLihkZWNsYXJhdGlvbi5raW5kID09IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiID8gZGVjbGFyYXRpb24ucGFyYW1ldGVycyA6IGRlY2xhcmF0aW9uLmZpZWxkcykubWFwKCh7bmFtZX0pID0+IG5hbWUpXG4gIF0ubWFwKHRhcmdldEtleSkpXG5cbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIGNvbnN0IHBhcmFtZXRlciA9IGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzW2luZGV4XVxuICAgIGNvbnN0IGtleXMgPSBwYXJhbWV0ZXIgJiYgdHlwZW9mIHBhcmFtZXRlciA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KHBhcmFtZXRlcilcbiAgICAgID8gT2JqZWN0LmtleXMocGFyYW1ldGVyKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIikgOiBcIlwiXG5cbiAgICBpZiAoIXBhcmFtZXRlciB8fCBwYXJhbWV0ZXIua2luZCAhPSBcIlR5cGVQYXJhbWV0ZXJcIiB8fCBrZXlzICE9IFwiaWQsa2luZCxsb2NhdGlvbixuYW1lXCIgfHxcbiAgICAgIHBhcmFtZXRlci5pZCAhPSBgJHtkZWNsYXJhdGlvbi5pZH06dHlwZToke2luZGV4fWApIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgdHlwZSBwYXJhbWV0ZXIgZGVjbGFyYXRpb25cIiwgcGFyYW1ldGVyPy5sb2NhdGlvbiA/PyBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICB9XG4gICAgcmVxdWlyZVNlbWFudGljTG9jYXRpb24ocGFyYW1ldGVyLmxvY2F0aW9uLCBsYW5ndWFnZSwgXCJ0eXBlIHBhcmFtZXRlciBsb2NhdGlvblwiLCBkZWNsYXJhdGlvbi5sb2NhdGlvbilcbiAgICB2YWxpZGF0ZVRhcmdldFR5cGVJZGVudGlmaWVyKGxhbmd1YWdlLCBwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyLmxvY2F0aW9uKVxuICAgIGNvbnN0IG5vcm1hbGl6ZWQgPSB0YXJnZXRLZXkocGFyYW1ldGVyLm5hbWUpXG5cbiAgICBpZiAobmFtZXMuaGFzKG5vcm1hbGl6ZWQpIHx8IHZhbHVlTmFtZXMuaGFzKG5vcm1hbGl6ZWQpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB0YXJnZXQgdHlwZSBwYXJhbWV0ZXIgY29sbGlzaW9uICcke3BhcmFtZXRlci5uYW1lfSdgLCBwYXJhbWV0ZXIubG9jYXRpb24pXG4gICAgfVxuICAgIG5hbWVzLmFkZChub3JtYWxpemVkKVxuICB9XG59XG5cbi8qKlxuICogRGV0ZWN0cyBUYXNrIDAxMiBJUiBiZWZvcmUgYSBub24tY29ob3J0IGJhY2tlbmQgcmVhY2hlcyBvbGRlciBmZWF0dXJlIGNoZWNrcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIENhbmRpZGF0ZSBtb2R1bGUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBnZW5lcmljIGRlY2xhcmF0aW9ucyBhcmUgcHJlc2VudC5cbiAqL1xuZnVuY3Rpb24gbW9kdWxlSGFzVHlwZVBhcmFtZXRlcnMobW9kdWxlKSB7XG4gIHJldHVybiBbLi4ubW9kdWxlLnJlY29yZHMgPz8gW10sIC4uLm1vZHVsZS5mdW5jdGlvbnNdLnNvbWUoKGRlY2xhcmF0aW9uKSA9PlxuICAgIEFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24/LnR5cGVQYXJhbWV0ZXJzKSAmJiBkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycy5sZW5ndGggPiAwKVxufVxuXG4vKipcbiAqIFJlamVjdHMgVGFzayAwMDggc3RhdGVtZW50cyBiZWZvcmUgYSBub24tY29ob3J0IGJhY2tlbmQgcmVhY2hlcyBjb2xsZWN0aW9uLXR5cGUgY2hlY2tzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gQ2FuZGlkYXRlIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZWplY3RJdGVyYXRpb25TdGF0ZW1lbnRzKG1vZHVsZSwgbGFuZ3VhZ2UpIHtcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB7XG4gICAgcmVqZWN0QmxvY2tJdGVyYXRpb24oZGVjbGFyYXRpb24gJiYgdHlwZW9mIGRlY2xhcmF0aW9uID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24pXG4gICAgICA/IFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcImJvZHlcIilcbiAgICAgIDogdW5kZWZpbmVkLCBsYW5ndWFnZSlcbiAgfVxuICByZWplY3RCbG9ja0l0ZXJhdGlvbihtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBsYW5ndWFnZSlcbn1cblxuLyoqXG4gKiBSZWplY3RzIFRhc2sgMDMyIElSIGJlZm9yZSBhIG5vbi1jb2hvcnQgYmFja2VuZCBhbGxvY2F0ZXMgb3V0cHV0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gQ2FuZGlkYXRlIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZWplY3RDb25kaXRpb25Db250cm9sbGVkTG9vcHMobW9kdWxlLCBsYW5ndWFnZSkge1xuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIHtcbiAgICByZWplY3RCbG9ja0NvbmRpdGlvbkxvb3AoZGVjbGFyYXRpb24gJiYgdHlwZW9mIGRlY2xhcmF0aW9uID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24pXG4gICAgICA/IFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcImJvZHlcIilcbiAgICAgIDogdW5kZWZpbmVkLCBsYW5ndWFnZSlcbiAgfVxuICByZWplY3RCbG9ja0NvbmRpdGlvbkxvb3AobW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgbGFuZ3VhZ2UpXG59XG5cbi8qKlxuICogRmluZHMgYSBjb25kaXRpb24tY29udHJvbGxlZCBsb29wIHdpdGhvdXQgZGVzY2VuZGluZyB0aHJvdWdoIG1hbGZvcm1lZCBvciBjeWNsaWMgY29udGFpbmVycy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gYmxvY2sgLSBDYW5kaWRhdGUgYmxvY2suXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJhY2tlbmRMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1NldDxvYmplY3Q+fSBbc2Vlbl0gLSBWaXNpdGVkIGNvbnRhaW5lcnMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmVqZWN0QmxvY2tDb25kaXRpb25Mb29wKGJsb2NrLCBsYW5ndWFnZSwgc2VlbiA9IG5ldyBTZXQoKSkge1xuICBpZiAoIWJsb2NrIHx8IHR5cGVvZiBibG9jayAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYmxvY2spIHx8IHNlZW4uaGFzKGJsb2NrKSkgcmV0dXJuXG4gIHNlZW4uYWRkKGJsb2NrKVxuICBjb25zdCBzdGF0ZW1lbnRzID0gUmVmbGVjdC5nZXQoYmxvY2ssIFwic3RhdGVtZW50c1wiKVxuXG4gIGlmICghQXJyYXkuaXNBcnJheShzdGF0ZW1lbnRzKSkgcmV0dXJuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIHN0YXRlbWVudHMpIHtcbiAgICBpZiAoIXN0YXRlbWVudCB8fCB0eXBlb2Ygc3RhdGVtZW50ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShzdGF0ZW1lbnQpKSBjb250aW51ZVxuICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwia2luZFwiKVxuICAgIGNvbnN0IGxvY2F0aW9uID0gZGlhZ25vc3RpY0xvY2F0aW9uKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJsb2NhdGlvblwiKSwgUmVmbGVjdC5nZXQoYmxvY2ssIFwibG9jYXRpb25cIikpXG5cbiAgICBpZiAoa2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAzMiBjb25kaXRpb24tY29udHJvbGxlZCBsb29wXCIsIGxvY2F0aW9uKVxuICAgIGlmIChraW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgcmVqZWN0QmxvY2tDb25kaXRpb25Mb29wKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJjb25zZXF1ZW50XCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICAgIHJlamVjdEJsb2NrQ29uZGl0aW9uTG9vcChSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiYWx0ZXJuYXRlXCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICB9IGVsc2UgaWYgKFtcIkZvckVhY2hTdGF0ZW1lbnRcIiwgXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIsIFwiV2hpbGVTdGF0ZW1lbnRcIl0uaW5jbHVkZXMoU3RyaW5nKGtpbmQpKSkge1xuICAgICAgcmVqZWN0QmxvY2tDb25kaXRpb25Mb29wKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJib2R5XCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICB9IGVsc2UgaWYgKGtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgcmVqZWN0QmxvY2tDb25kaXRpb25Mb29wKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJib2R5XCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICAgIHJlamVjdEJsb2NrQ29uZGl0aW9uTG9vcChSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiY2F0Y2hCb2R5XCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBGaW5kcyBhIFRhc2sgMDA4IG5vZGUgd2l0aG91dCBkZXNjZW5kaW5nIHRocm91Z2ggbWFsZm9ybWVkIG9yIGN5Y2xpYyBjb250YWluZXJzLlxuICogQHBhcmFtIHt1bmtub3dufSBibG9jayAtIENhbmRpZGF0ZSBibG9jay5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFtzZWVuXSAtIFZpc2l0ZWQgY29udGFpbmVycy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiByZWplY3RCbG9ja0l0ZXJhdGlvbihibG9jaywgbGFuZ3VhZ2UsIHNlZW4gPSBuZXcgU2V0KCkpIHtcbiAgaWYgKCFibG9jayB8fCB0eXBlb2YgYmxvY2sgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGJsb2NrKSB8fCBzZWVuLmhhcyhibG9jaykpIHJldHVyblxuICBzZWVuLmFkZChibG9jaylcbiAgY29uc3Qgc3RhdGVtZW50cyA9IFJlZmxlY3QuZ2V0KGJsb2NrLCBcInN0YXRlbWVudHNcIilcblxuICBpZiAoIUFycmF5LmlzQXJyYXkoc3RhdGVtZW50cykpIHJldHVyblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBzdGF0ZW1lbnRzKSB7XG4gICAgaWYgKCFzdGF0ZW1lbnQgfHwgdHlwZW9mIHN0YXRlbWVudCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoc3RhdGVtZW50KSkgY29udGludWVcbiAgICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImtpbmRcIilcbiAgICBjb25zdCBsb2NhdGlvbiA9IGRpYWdub3N0aWNMb2NhdGlvbihSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwibG9jYXRpb25cIiksIFJlZmxlY3QuZ2V0KGJsb2NrLCBcImxvY2F0aW9uXCIpKVxuXG4gICAgaWYgKFtcIkZvckVhY2hTdGF0ZW1lbnRcIiwgXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIsIFwiQnJlYWtTdGF0ZW1lbnRcIiwgXCJDb250aW51ZVN0YXRlbWVudFwiXS5pbmNsdWRlcyhraW5kKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDA4IG9yZGVyZWQgbGlzdCBpdGVyYXRpb25cIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChraW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgcmVqZWN0QmxvY2tJdGVyYXRpb24oUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImNvbnNlcXVlbnRcIiksIGxhbmd1YWdlLCBzZWVuKVxuICAgICAgcmVqZWN0QmxvY2tJdGVyYXRpb24oUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImFsdGVybmF0ZVwiKSwgbGFuZ3VhZ2UsIHNlZW4pXG4gICAgfSBlbHNlIGlmIChraW5kID09IFwiVHJ5U3RhdGVtZW50XCIpIHtcbiAgICAgIHJlamVjdEJsb2NrSXRlcmF0aW9uKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJib2R5XCIpLCBsYW5ndWFnZSwgc2VlbilcbiAgICAgIHJlamVjdEJsb2NrSXRlcmF0aW9uKFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJjYXRjaEJvZHlcIiksIGxhbmd1YWdlLCBzZWVuKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlamVjdHMgVGFzayAwMDcgb3B0aW9uYWwgdHlwZXMgYmVmb3JlIGEgbm9uLWNvaG9ydCBlbWl0dGVyIGFsbG9jYXRlcyBvdXRwdXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBDYW5kaWRhdGUgc2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGlkZW50aXR5LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlamVjdE9wdGlvbmFsVHlwZXMobW9kdWxlLCBsYW5ndWFnZSkge1xuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5mdW5jdGlvbnMpIHtcbiAgICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoZGVjbGFyYXRpb24pKSBjb250aW51ZVxuICAgIGNvbnN0IGxvY2F0aW9uID0gUmVmbGVjdC5nZXQoZGVjbGFyYXRpb24sIFwibG9jYXRpb25cIikgPz8gbW9kdWxlLmxvY2F0aW9uXG5cbiAgICBpZiAoY29udGFpbnNPcHRpb25hbFR5cGUoUmVmbGVjdC5nZXQoZGVjbGFyYXRpb24sIFwicmV0dXJuVHlwZVwiKSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNyBvcHRpb25hbCByZXR1cm4gdHlwZVwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgQXJyYXkuaXNBcnJheShSZWZsZWN0LmdldChkZWNsYXJhdGlvbiwgXCJwYXJhbWV0ZXJzXCIpKSA/IFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcInBhcmFtZXRlcnNcIikgOiBbXSkge1xuICAgICAgaWYgKGNvbnRhaW5zT3B0aW9uYWxUeXBlKHBhcmFtZXRlcj8udHlwZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDA3IG9wdGlvbmFsIHBhcmFtZXRlciB0eXBlXCIsIHBhcmFtZXRlci5sb2NhdGlvbiA/PyBsb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgcmVqZWN0QmxvY2tPcHRpb25hbFR5cGVzKFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcImJvZHlcIiksIGxhbmd1YWdlKVxuICB9XG4gIHJlamVjdEJsb2NrT3B0aW9uYWxUeXBlcyhtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBsYW5ndWFnZSlcbn1cblxuLyoqXG4gKiBSZWplY3RzIG9wdGlvbmFsIGxvY2FsIHR5cGVzIHJlY3Vyc2l2ZWx5IGluIG9uZSBjYW5kaWRhdGUgYmxvY2suXG4gKiBAcGFyYW0ge3Vua25vd259IGJsb2NrIC0gQ2FuZGlkYXRlIGJsb2NrLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGlkZW50aXR5LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlamVjdEJsb2NrT3B0aW9uYWxUeXBlcyhibG9jaywgbGFuZ3VhZ2UpIHtcbiAgaWYgKCFibG9jayB8fCB0eXBlb2YgYmxvY2sgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGJsb2NrKSB8fCAhQXJyYXkuaXNBcnJheShSZWZsZWN0LmdldChibG9jaywgXCJzdGF0ZW1lbnRzXCIpKSkgcmV0dXJuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIFJlZmxlY3QuZ2V0KGJsb2NrLCBcInN0YXRlbWVudHNcIikpIHtcbiAgICBpZiAoIXN0YXRlbWVudCB8fCB0eXBlb2Ygc3RhdGVtZW50ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShzdGF0ZW1lbnQpKSBjb250aW51ZVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiAmJiBjb250YWluc09wdGlvbmFsVHlwZShzdGF0ZW1lbnQudHlwZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNyBvcHRpb25hbCBsb2NhbCB0eXBlXCIsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgcmVqZWN0QmxvY2tPcHRpb25hbFR5cGVzKHN0YXRlbWVudC5jb25zZXF1ZW50LCBsYW5ndWFnZSlcbiAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSByZWplY3RCbG9ja09wdGlvbmFsVHlwZXMoc3RhdGVtZW50LmFsdGVybmF0ZSwgbGFuZ3VhZ2UpXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIikge1xuICAgICAgaWYgKGNvbnRhaW5zT3B0aW9uYWxUeXBlKHN0YXRlbWVudC52YWx1ZUJpbmRpbmc/LnR5cGUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNyBvcHRpb25hbCBpdGVyYXRpb24gYmluZGluZyB0eXBlXCIsIHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubG9jYXRpb24gPz8gc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgcmVqZWN0QmxvY2tPcHRpb25hbFR5cGVzKHN0YXRlbWVudC5ib2R5LCBsYW5ndWFnZSlcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikgcmVqZWN0QmxvY2tPcHRpb25hbFR5cGVzKHN0YXRlbWVudC5ib2R5LCBsYW5ndWFnZSlcbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgcmVqZWN0QmxvY2tPcHRpb25hbFR5cGVzKHN0YXRlbWVudC5ib2R5LCBsYW5ndWFnZSlcbiAgICAgIHJlamVjdEJsb2NrT3B0aW9uYWxUeXBlcyhzdGF0ZW1lbnQuY2F0Y2hCb2R5LCBsYW5ndWFnZSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGJvdW5kZWQgcmVjdXJzaXZlIHNlbWFudGljIHR5cGUgZm9yIGFuIG9wdGlvbmFsIG5vZGUuXG4gKiBAcGFyYW0ge3Vua25vd259IHR5cGUgLSBDYW5kaWRhdGUgdHlwZS5cbiAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFtzZWVuXSAtIEN5Y2xlIHByb3RlY3Rpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBhbiBvcHRpb25hbCB0eXBlIG9jY3Vycy5cbiAqL1xuZnVuY3Rpb24gY29udGFpbnNPcHRpb25hbFR5cGUodHlwZSwgc2VlbiA9IG5ldyBTZXQoKSkge1xuICBpZiAoIXR5cGUgfHwgdHlwZW9mIHR5cGUgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHR5cGUpIHx8IHNlZW4uaGFzKHR5cGUpKSByZXR1cm4gZmFsc2VcbiAgc2Vlbi5hZGQodHlwZSlcbiAgY29uc3Qga2luZCA9IFJlZmxlY3QuZ2V0KHR5cGUsIFwia2luZFwiKVxuXG4gIGlmIChraW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHJldHVybiB0cnVlXG4gIGlmIChraW5kID09IFwiTGlzdFR5cGVcIikgcmV0dXJuIGNvbnRhaW5zT3B0aW9uYWxUeXBlKFJlZmxlY3QuZ2V0KHR5cGUsIFwiZWxlbWVudFR5cGVcIiksIHNlZW4pXG4gIGlmIChraW5kID09IFwiTWFwVHlwZVwiIHx8IGtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSByZXR1cm4gY29udGFpbnNPcHRpb25hbFR5cGUoUmVmbGVjdC5nZXQodHlwZSwgXCJrZXlUeXBlXCIpLCBzZWVuKSB8fFxuICAgIGNvbnRhaW5zT3B0aW9uYWxUeXBlKFJlZmxlY3QuZ2V0KHR5cGUsIFwidmFsdWVUeXBlXCIpLCBzZWVuKVxuXG4gIHJldHVybiBmYWxzZVxufVxuXG4vKipcbiAqIFJlamVjdHMgVGFzayAwMDYgdHlwZXMgYmVmb3JlIGEgcmVnaXN0ZXJlZCBub24tY29ob3J0IGVtaXR0ZXIgY2FuIGFsbG9jYXRlIGFuIGFydGlmYWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGlkZW50aXR5LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlamVjdENvbGxlY3Rpb25UeXBlcyhtb2R1bGUsIGxhbmd1YWdlKSB7XG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgIGlmICghZGVjbGFyYXRpb24gfHwgdHlwZW9mIGRlY2xhcmF0aW9uICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShkZWNsYXJhdGlvbikpIGNvbnRpbnVlXG4gICAgY29uc3QgbG9jYXRpb24gPSBSZWZsZWN0LmdldChkZWNsYXJhdGlvbiwgXCJsb2NhdGlvblwiKSA/PyBtb2R1bGUubG9jYXRpb25cbiAgICBjb25zdCByZXR1cm5UeXBlID0gUmVmbGVjdC5nZXQoZGVjbGFyYXRpb24sIFwicmV0dXJuVHlwZVwiKVxuXG4gICAgaWYgKGlzQ29sbGVjdGlvblR5cGUocmV0dXJuVHlwZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNiBpbW11dGFibGUgY29sbGVjdGlvbiByZXR1cm4gdHlwZVwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgcGFyYW1ldGVycyA9IFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcInBhcmFtZXRlcnNcIilcblxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIEFycmF5LmlzQXJyYXkocGFyYW1ldGVycykgPyBwYXJhbWV0ZXJzIDogW10pIHtcbiAgICAgIGlmIChpc0NvbGxlY3Rpb25UeXBlKHBhcmFtZXRlcj8udHlwZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNiBpbW11dGFibGUgY29sbGVjdGlvbiBwYXJhbWV0ZXIgdHlwZVwiLCBwYXJhbWV0ZXIubG9jYXRpb24gPz8gbG9jYXRpb24pXG4gICAgfVxuICAgIHJlamVjdEJsb2NrQ29sbGVjdGlvblR5cGVzKFJlZmxlY3QuZ2V0KGRlY2xhcmF0aW9uLCBcImJvZHlcIiksIGxhbmd1YWdlKVxuICB9XG4gIHJlamVjdEJsb2NrQ29sbGVjdGlvblR5cGVzKG1vZHVsZS5lbnRyeVBvaW50LmJvZHksIGxhbmd1YWdlKVxufVxuXG4vKipcbiAqIFJlamVjdHMgY29sbGVjdGlvbiBsb2NhbCB0eXBlcyByZWN1cnNpdmVseSBpbiBvbmUgYmxvY2suXG4gKiBAcGFyYW0ge3Vua25vd259IGJsb2NrIC0gQ2FuZGlkYXRlIHNlbWFudGljIGJsb2NrLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gVGFyZ2V0IGlkZW50aXR5LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlamVjdEJsb2NrQ29sbGVjdGlvblR5cGVzKGJsb2NrLCBsYW5ndWFnZSkge1xuICBpZiAoIWJsb2NrIHx8IHR5cGVvZiBibG9jayAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYmxvY2spIHx8ICFBcnJheS5pc0FycmF5KFJlZmxlY3QuZ2V0KGJsb2NrLCBcInN0YXRlbWVudHNcIikpKSByZXR1cm5cbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgUmVmbGVjdC5nZXQoYmxvY2ssIFwic3RhdGVtZW50c1wiKSkge1xuICAgIGlmICghc3RhdGVtZW50IHx8IHR5cGVvZiBzdGF0ZW1lbnQgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHN0YXRlbWVudCkpIGNvbnRpbnVlXG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiICYmIGlzQ29sbGVjdGlvblR5cGUoc3RhdGVtZW50LnR5cGUpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMDYgaW1tdXRhYmxlIGNvbGxlY3Rpb24gbG9jYWwgdHlwZVwiLCBzdGF0ZW1lbnQubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgIHJlamVjdEJsb2NrQ29sbGVjdGlvblR5cGVzKHN0YXRlbWVudC5jb25zZXF1ZW50LCBsYW5ndWFnZSlcbiAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSByZWplY3RCbG9ja0NvbGxlY3Rpb25UeXBlcyhzdGF0ZW1lbnQuYWx0ZXJuYXRlLCBsYW5ndWFnZSlcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgICBpZiAoaXNDb2xsZWN0aW9uVHlwZShzdGF0ZW1lbnQudmFsdWVCaW5kaW5nPy50eXBlKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMDYgaW1tdXRhYmxlIGNvbGxlY3Rpb24gaXRlcmF0aW9uIGJpbmRpbmcgdHlwZVwiLCBzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLmxvY2F0aW9uID8/IHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIHJlamVjdEJsb2NrQ29sbGVjdGlvblR5cGVzKHN0YXRlbWVudC5ib2R5LCBsYW5ndWFnZSlcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikgcmVqZWN0QmxvY2tDb2xsZWN0aW9uVHlwZXMoc3RhdGVtZW50LmJvZHksIGxhbmd1YWdlKVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiKSB7XG4gICAgICByZWplY3RCbG9ja0NvbGxlY3Rpb25UeXBlcyhzdGF0ZW1lbnQuYm9keSwgbGFuZ3VhZ2UpXG4gICAgICByZWplY3RCbG9ja0NvbGxlY3Rpb25UeXBlcyhzdGF0ZW1lbnQuY2F0Y2hCb2R5LCBsYW5ndWFnZSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3MgYSBwb3NzaWJsZSByZWN1cnNpdmUgY29sbGVjdGlvbiB0eXBlIHdpdGhvdXQgdHJhdmVyc2luZyBtYWxmb3JtZWQgY2hpbGRyZW4uXG4gKiBAcGFyYW0ge3Vua25vd259IHR5cGUgLSBDYW5kaWRhdGUgdHlwZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBvdXRlciB0eXBlIGlzIGEgY29sbGVjdGlvbi5cbiAqL1xuZnVuY3Rpb24gaXNDb2xsZWN0aW9uVHlwZSh0eXBlKSB7XG4gIHJldHVybiBCb29sZWFuKHR5cGUgJiYgdHlwZW9mIHR5cGUgPT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh0eXBlKSAmJlxuICAgIChbXCJMaXN0VHlwZVwiLCBcIk1hcFR5cGVcIiwgXCJPcmRlcmVkTWFwVHlwZVwiXS5pbmNsdWRlcyhTdHJpbmcoUmVmbGVjdC5nZXQodHlwZSwgXCJraW5kXCIpKSkpKVxufVxuXG4vKipcbiAqIFJlamVjdHMgc2VtYW50aWMgbmFtZXMgdGhhdCB3b3VsZCBjYXB0dXJlIHN5bnRheCBvd25lZCBieSBvbmUgYmFja2VuZCBlbWl0dGVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gU2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gQmFja2VuZCBsYW5ndWFnZSBvciBiaW5hcnkgdGFyZ2V0LlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlU2NhZmZvbGRpbmdOYW1lcyhtb2R1bGUsIGxhbmd1YWdlKSB7XG4gIHZhbGlkYXRlUmVjb3JkQ29uc3RydWN0b3JOYW1lcyhtb2R1bGUsIGxhbmd1YWdlKVxuICBjb25zdCBuZWVkc05hdGl2ZU1hcCA9IFtcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCJdLmluY2x1ZGVzKGxhbmd1YWdlKSAmJlxuICAgIChtb2R1bGVDb250YWluc0V4cHJlc3Npb25LaW5kKG1vZHVsZSwgXCJNYXBMaXRlcmFsXCIpIHx8IG1vZHVsZUNvbnRhaW5zRXhwcmVzc2lvbktpbmQobW9kdWxlLCBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpKVxuICBjb25zdCBuZWVkc1BocENvdW50ID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiAmJiBtb2R1bGVDb250YWluc0V4cHJlc3Npb25LaW5kKG1vZHVsZSwgXCJDb2xsZWN0aW9uU2l6ZUV4cHJlc3Npb25cIilcbiAgY29uc3QgamF2YXNjcmlwdE93bmVkTmFtZXMgPSBuZXcgU2V0KFtcImNvbnNvbGVcIiwgLi4uKG5lZWRzTmF0aXZlTWFwID8gW1wiTWFwXCJdIDogW10pXSlcbiAgY29uc3Qgb3duZWRFbnRyeU5hbWVzID0gbGFuZ3VhZ2UgPT0gXCJnb1wiID8gbmV3IFNldChbXCJmbXRcIiwgXCJpbnQ2NFwiLCBcImJvb2xcIiwgXCJzdHJpbmdcIiwgXCJ0cnVlXCIsIFwiZmFsc2VcIl0pIDpcbiAgICBsYW5ndWFnZSA9PSBcImNzaGFycFwiID8gbmV3IFNldChbXCJTeXN0ZW1cIl0pIDogbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBuZXcgU2V0KFtcImFyZ3NcIiwgXCJTeXN0ZW1cIl0pIDpcbiAgICBbXCJqYXZhc2NyaXB0XCIsIFwidHlwZXNjcmlwdFwiXS5pbmNsdWRlcyhsYW5ndWFnZSkgPyBqYXZhc2NyaXB0T3duZWROYW1lcyA6IG5ldyBTZXQoKVxuICBjb25zdCBvd25lZFByaW50UmVjZWl2ZXJOYW1lcyA9IGxhbmd1YWdlID09IFwiZ29cIiA/IG5ldyBTZXQoW1wiZm10XCIsIFwiaW50NjRcIiwgXCJib29sXCIsIFwic3RyaW5nXCIsIFwidHJ1ZVwiLCBcImZhbHNlXCJdKSA6XG4gICAgbGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiB8fCBsYW5ndWFnZSA9PSBcImphdmFcIiA/IG5ldyBTZXQoW1wiU3lzdGVtXCJdKSA6XG4gICAgW1wiamF2YXNjcmlwdFwiLCBcInR5cGVzY3JpcHRcIl0uaW5jbHVkZXMobGFuZ3VhZ2UpID8gamF2YXNjcmlwdE93bmVkTmFtZXMgOiBuZXcgU2V0KClcbiAgY29uc3Qgb3duZWRDYWxsYWJsZU5hbWVzID0gbGFuZ3VhZ2UgPT0gXCJnb1wiID8gbmV3IFNldChbXCJtYWluXCIsIFwiaW5pdFwiLCBcImZtdFwiLCBcImludDY0XCIsIFwiYm9vbFwiLCBcInN0cmluZ1wiLCBcInRydWVcIiwgXCJmYWxzZVwiXSkgOlxuICAgIGxhbmd1YWdlID09IFwiY3NoYXJwXCIgPyBuZXcgU2V0KFtcbiAgICBcIkVxdWFsc1wiLCBcIkZpbmFsaXplXCIsIFwiR2V0SGFzaENvZGVcIiwgXCJHZXRUeXBlXCIsIFwiTWFpblwiLCBcIk1lbWJlcndpc2VDbG9uZVwiLCBcIlByb2dyYW1cIiwgXCJSZWZlcmVuY2VFcXVhbHNcIiwgXCJTeXN0ZW1cIiwgXCJUb1N0cmluZ1wiXG4gIF0pIDpcbiAgICBsYW5ndWFnZSA9PSBcImphdmFcIiA/IG5ldyBTZXQoW1wibWFpblwiXSkgOlxuICAgIFtcImphdmFzY3JpcHRcIiwgXCJ0eXBlc2NyaXB0XCJdLmluY2x1ZGVzKGxhbmd1YWdlKSA/IGphdmFzY3JpcHRPd25lZE5hbWVzIDpcbiAgICBuZWVkc1BocENvdW50ID8gbmV3IFNldChbXCJjb3VudFwiXSkgOlxuICAgIGxhbmd1YWdlID09IFwicnVieVwiID8gbmV3IFNldChbXCJwdXRzXCIsIFwic2VuZFwiLCBcInB1YmxpY19zZW5kXCIsIFwiX19zZW5kX19cIl0pIDogbmV3IFNldCgpXG4gIC8qKlxuICAgKiBQcm90ZWN0cyBwcmludC9mYWN0b3J5IHNwZWxsaW5ncyBpbnNpZGUgb25lIGNhbGxhYmxlIHNjb3BlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gQ2FsbGFibGUgcGFyYW1ldGVycy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYm9keSAtIENhbGxhYmxlIGJvZHkuXG4gICAqIEBwYXJhbSB7XCJmdW5jdGlvblwiIHwgXCJjb25zdHJ1Y3RvclwiIHwgXCJtZXRob2RcIn0gb3duZXIgLSBEaWFnbm9zdGljIG93bmVyLlxuICAgKi9cbiAgY29uc3QgdmFsaWRhdGVDYWxsYWJsZUJpbmRpbmdzID0gKHBhcmFtZXRlcnMsIGJvZHksIG93bmVyKSA9PiB7XG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgcGFyYW1ldGVycykge1xuICAgICAgaWYgKG93bmVkUHJpbnRSZWNlaXZlck5hbWVzLmhhcyhwYXJhbWV0ZXIubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgJHtvd25lcn0gcGFyYW1ldGVyICcke3BhcmFtZXRlci5uYW1lfScgY2FwdHVyZXMgYmFja2VuZCBzY2FmZm9sZGluZ2AsIHBhcmFtZXRlci5sb2NhdGlvbilcbiAgICAgIH1cbiAgICB9XG4gICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgYWxsU3RhdGVtZW50cyhib2R5KSkge1xuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiICYmIG93bmVkUHJpbnRSZWNlaXZlck5hbWVzLmhhcyhzdGF0ZW1lbnQubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgJHtvd25lcn0gbG9jYWwgJyR7c3RhdGVtZW50Lm5hbWV9JyBjYXB0dXJlcyBiYWNrZW5kIHNjYWZmb2xkaW5nYCwgc3RhdGVtZW50LmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiICYmIG93bmVkUHJpbnRSZWNlaXZlck5hbWVzLmhhcyhzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLm5hbWUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYCR7b3duZXJ9IGl0ZXJhdGlvbiBiaW5kaW5nICcke3N0YXRlbWVudC52YWx1ZUJpbmRpbmcubmFtZX0nIGNhcHR1cmVzIGJhY2tlbmQgc2NhZmZvbGRpbmdgLFxuICAgICAgICAgIHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubG9jYXRpb24pXG4gICAgICB9XG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIpIHtcbiAgICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIFtzdGF0ZW1lbnQua2V5QmluZGluZywgc3RhdGVtZW50LnZhbHVlQmluZGluZ10pIHtcbiAgICAgICAgICBpZiAob3duZWRQcmludFJlY2VpdmVyTmFtZXMuaGFzKGJpbmRpbmcubmFtZSkpIHtcbiAgICAgICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYCR7b3duZXJ9IGl0ZXJhdGlvbiBiaW5kaW5nICcke2JpbmRpbmcubmFtZX0nIGNhcHR1cmVzIGJhY2tlbmQgc2NhZmZvbGRpbmdgLCBiaW5kaW5nLmxvY2F0aW9uKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiVHJ5U3RhdGVtZW50XCIgJiYgb3duZWRQcmludFJlY2VpdmVyTmFtZXMuaGFzKHN0YXRlbWVudC5jYXRjaEJpbmRpbmcubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgJHtvd25lcn0gY2F0Y2ggYmluZGluZyAnJHtzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLm5hbWV9JyBjYXB0dXJlcyBiYWNrZW5kIHNjYWZmb2xkaW5nYCxcbiAgICAgICAgICBzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLmxvY2F0aW9uKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGFsbFN0YXRlbWVudHMobW9kdWxlLmVudHJ5UG9pbnQuYm9keSkpIHtcbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgJiYgb3duZWRFbnRyeU5hbWVzLmhhcyhzdGF0ZW1lbnQubmFtZSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGVudHJ5IGxvY2FsICcke3N0YXRlbWVudC5uYW1lfScgY2FwdHVyZXMgYmFja2VuZCBzY2FmZm9sZGluZ2AsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaFN0YXRlbWVudFwiICYmIG93bmVkRW50cnlOYW1lcy5oYXMoc3RhdGVtZW50LnZhbHVlQmluZGluZy5uYW1lKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgZW50cnkgaXRlcmF0aW9uIGJpbmRpbmcgJyR7c3RhdGVtZW50LnZhbHVlQmluZGluZy5uYW1lfScgY2FwdHVyZXMgYmFja2VuZCBzY2FmZm9sZGluZ2AsXG4gICAgICAgIHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIikge1xuICAgICAgZm9yIChjb25zdCBiaW5kaW5nIG9mIFtzdGF0ZW1lbnQua2V5QmluZGluZywgc3RhdGVtZW50LnZhbHVlQmluZGluZ10pIHtcbiAgICAgICAgaWYgKG93bmVkRW50cnlOYW1lcy5oYXMoYmluZGluZy5uYW1lKSkge1xuICAgICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGVudHJ5IGl0ZXJhdGlvbiBiaW5kaW5nICcke2JpbmRpbmcubmFtZX0nIGNhcHR1cmVzIGJhY2tlbmQgc2NhZmZvbGRpbmdgLCBiaW5kaW5nLmxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlRyeVN0YXRlbWVudFwiICYmIG93bmVkRW50cnlOYW1lcy5oYXMoc3RhdGVtZW50LmNhdGNoQmluZGluZy5uYW1lKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgZW50cnkgY2F0Y2ggYmluZGluZyAnJHtzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLm5hbWV9JyBjYXB0dXJlcyBiYWNrZW5kIHNjYWZmb2xkaW5nYCxcbiAgICAgICAgc3RhdGVtZW50LmNhdGNoQmluZGluZy5sb2NhdGlvbilcbiAgICB9XG4gIH1cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB7XG4gICAgY29uc3QgdGFyZ2V0TmFtZSA9IGxhbmd1YWdlID09IFwicGhwXCIgPyBkZWNsYXJhdGlvbi5uYW1lLnRvTG93ZXJDYXNlKCkgOiBkZWNsYXJhdGlvbi5uYW1lXG5cbiAgICBpZiAob3duZWRDYWxsYWJsZU5hbWVzLmhhcyh0YXJnZXROYW1lKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgZnVuY3Rpb24gJyR7ZGVjbGFyYXRpb24ubmFtZX0nIGNhcHR1cmVzIGJhY2tlbmQgc2NhZmZvbGRpbmdgLCBkZWNsYXJhdGlvbk5hbWVMb2NhdGlvbihkZWNsYXJhdGlvbikpXG4gICAgfVxuICAgIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIikge1xuICAgICAgY29uc3Qgc2lnbmF0dXJlID0gZW1pdHRlZEphdmFGdW5jdGlvblNpZ25hdHVyZShkZWNsYXJhdGlvbilcblxuICAgICAgaWYgKHNpZ25hdHVyZSAmJiBqYXZhT2JqZWN0SW5zdGFuY2VNZXRob2RTaWduYXR1cmVzLmhhcyhzaWduYXR1cmUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShcbiAgICAgICAgICBsYW5ndWFnZSxcbiAgICAgICAgICBgZnVuY3Rpb24gJyR7c2lnbmF0dXJlfScgY29uZmxpY3RzIHdpdGggYW4gaW5oZXJpdGVkIGphdmEubGFuZy5PYmplY3QgaW5zdGFuY2UgbWV0aG9kYCxcbiAgICAgICAgICBkZWNsYXJhdGlvbk5hbWVMb2NhdGlvbihkZWNsYXJhdGlvbilcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgICB2YWxpZGF0ZUNhbGxhYmxlQmluZGluZ3MoZGVjbGFyYXRpb24ucGFyYW1ldGVycywgZGVjbGFyYXRpb24uYm9keSwgXCJmdW5jdGlvblwiKVxuICB9XG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmNsYXNzZXMgPz8gW10pIHtcbiAgICB2YWxpZGF0ZUNhbGxhYmxlQmluZGluZ3MoZGVjbGFyYXRpb24uY29uc3RydWN0b3IucGFyYW1ldGVycywgZGVjbGFyYXRpb24uY29uc3RydWN0b3IuYm9keSwgXCJjb25zdHJ1Y3RvclwiKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIHZhbGlkYXRlQ2FsbGFibGVCaW5kaW5ncyhtZXRob2QucGFyYW1ldGVycywgbWV0aG9kLmJvZHksIFwibWV0aG9kXCIpXG4gIH1cbiAgaWYgKGxhbmd1YWdlID09IFwiamF2YVwiKSB2YWxpZGF0ZUphdmFVdGlsRmFjdG9yeU5hbWVzKG1vZHVsZSlcbn1cblxuLyoqXG4gKiBSZWplY3RzIEphdmFTY3JpcHQtZmFtaWx5IGxleGljYWwgYmluZGluZ3MgdGhhdCBjYW4gY2FwdHVyZSBlbWl0dGVkIGJhcmUgcmVjb3JkIGNvbnN0cnVjdG9yIG5hbWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gVmFsaWRhdGVkLXNoYXBlIHNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVJlY29yZENvbnN0cnVjdG9yTmFtZXMobW9kdWxlLCBsYW5ndWFnZSkge1xuICBpZiAobGFuZ3VhZ2UgIT0gXCJqYXZhc2NyaXB0XCIgJiYgbGFuZ3VhZ2UgIT0gXCJ0eXBlc2NyaXB0XCIpIHJldHVyblxuICBjb25zdCByZWNvcmROYW1lcyA9IG5ldyBTZXQoW1xuICAgIC4uLihtb2R1bGUucmVjb3JkcyA/PyBbXSkubWFwKChyZWNvcmQpID0+IHJlY29yZC5uYW1lKSxcbiAgICAuLi4obW9kdWxlLmNsYXNzZXMgPz8gW10pLm1hcCgoZGVjbGFyYXRpb24pID0+IGRlY2xhcmF0aW9uLm5hbWUpLFxuICAgIC4uLihtb2R1bGUuZXJyb3JzID8/IFtdKS5tYXAoKGVycm9yKSA9PiBlcnJvci5uYW1lKVxuICBdKVxuXG4gIC8qKlxuICAgKiBDaGVja3MgZGVjbGFyYXRpb25zIG5lc3RlZCBiZW5lYXRoIG9uZSBvd25pbmcgYmxvY2suXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gQmxvY2sgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtcImVudHJ5XCIgfCBcImZ1bmN0aW9uXCIgfCBcImNvbnN0cnVjdG9yXCIgfCBcIm1ldGhvZFwifSBvd25lciAtIE93bmluZyBzY29wZSBraW5kLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNvbnN0IHZhbGlkYXRlQmxvY2tOYW1lcyA9IChibG9jaywgb3duZXIpID0+IHtcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBhbGxTdGF0ZW1lbnRzKGJsb2NrKSkge1xuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiICYmIHJlY29yZE5hbWVzLmhhcyhzdGF0ZW1lbnQubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgJHtvd25lcn0gbG9jYWwgJyR7c3RhdGVtZW50Lm5hbWV9JyBjYXB0dXJlcyByZWNvcmQgY29uc3RydWN0b3JgLCBiaW5kaW5nTmFtZUxvY2F0aW9uKHN0YXRlbWVudCkpXG4gICAgICB9XG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoU3RhdGVtZW50XCIgJiYgcmVjb3JkTmFtZXMuaGFzKHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFxuICAgICAgICAgIGxhbmd1YWdlLFxuICAgICAgICAgIGAke293bmVyfSBpdGVyYXRpb24gYmluZGluZyAnJHtzdGF0ZW1lbnQudmFsdWVCaW5kaW5nLm5hbWV9JyBjYXB0dXJlcyByZWNvcmQgY29uc3RydWN0b3JgLFxuICAgICAgICAgIGJpbmRpbmdOYW1lTG9jYXRpb24oc3RhdGVtZW50LnZhbHVlQmluZGluZylcbiAgICAgICAgKVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgICAgIGZvciAoY29uc3QgYmluZGluZyBvZiBbc3RhdGVtZW50LmtleUJpbmRpbmcsIHN0YXRlbWVudC52YWx1ZUJpbmRpbmddKSB7XG4gICAgICAgICAgaWYgKHJlY29yZE5hbWVzLmhhcyhiaW5kaW5nLm5hbWUpKSB7XG4gICAgICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGAke293bmVyfSBpdGVyYXRpb24gYmluZGluZyAnJHtiaW5kaW5nLm5hbWV9JyBjYXB0dXJlcyByZWNvcmQgY29uc3RydWN0b3JgLFxuICAgICAgICAgICAgICBiaW5kaW5nTmFtZUxvY2F0aW9uKGJpbmRpbmcpKVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiVHJ5U3RhdGVtZW50XCIgJiYgcmVjb3JkTmFtZXMuaGFzKHN0YXRlbWVudC5jYXRjaEJpbmRpbmcubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KFxuICAgICAgICAgIGxhbmd1YWdlLFxuICAgICAgICAgIGAke293bmVyfSBjYXRjaCBiaW5kaW5nICcke3N0YXRlbWVudC5jYXRjaEJpbmRpbmcubmFtZX0nIGNhcHR1cmVzIG5vbWluYWwgY29uc3RydWN0b3JgLFxuICAgICAgICAgIGJpbmRpbmdOYW1lTG9jYXRpb24oc3RhdGVtZW50LmNhdGNoQmluZGluZylcbiAgICAgICAgKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlQmxvY2tOYW1lcyhtb2R1bGUuZW50cnlQb2ludC5ib2R5LCBcImVudHJ5XCIpXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykge1xuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMpIHtcbiAgICAgIGlmIChyZWNvcmROYW1lcy5oYXMocGFyYW1ldGVyLm5hbWUpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGZ1bmN0aW9uIHBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nIGNhcHR1cmVzIHJlY29yZCBjb25zdHJ1Y3RvcmAsIGJpbmRpbmdOYW1lTG9jYXRpb24ocGFyYW1ldGVyKSlcbiAgICAgIH1cbiAgICB9XG4gICAgdmFsaWRhdGVCbG9ja05hbWVzKGRlY2xhcmF0aW9uLmJvZHksIFwiZnVuY3Rpb25cIilcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIG1vZHVsZS5jbGFzc2VzID8/IFtdKSB7XG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgZGVjbGFyYXRpb24uY29uc3RydWN0b3IucGFyYW1ldGVycykge1xuICAgICAgaWYgKHJlY29yZE5hbWVzLmhhcyhwYXJhbWV0ZXIubmFtZSkpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgY29uc3RydWN0b3IgcGFyYW1ldGVyICcke3BhcmFtZXRlci5uYW1lfScgY2FwdHVyZXMgbm9taW5hbCBjb25zdHJ1Y3RvcmAsXG4gICAgICAgICAgYmluZGluZ05hbWVMb2NhdGlvbihwYXJhbWV0ZXIpKVxuICAgICAgfVxuICAgIH1cbiAgICB2YWxpZGF0ZUJsb2NrTmFtZXMoZGVjbGFyYXRpb24uY29uc3RydWN0b3IuYm9keSwgXCJjb25zdHJ1Y3RvclwiKVxuICAgIGZvciAoY29uc3QgbWV0aG9kIG9mIGRlY2xhcmF0aW9uLm1ldGhvZHMpIHtcbiAgICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIG1ldGhvZC5wYXJhbWV0ZXJzKSB7XG4gICAgICAgIGlmIChyZWNvcmROYW1lcy5oYXMocGFyYW1ldGVyLm5hbWUpKSB7XG4gICAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgbWV0aG9kIHBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nIGNhcHR1cmVzIG5vbWluYWwgY29uc3RydWN0b3JgLFxuICAgICAgICAgICAgYmluZGluZ05hbWVMb2NhdGlvbihwYXJhbWV0ZXIpKVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB2YWxpZGF0ZUJsb2NrTmFtZXMobWV0aG9kLmJvZHksIFwibWV0aG9kXCIpXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogUmVqZWN0cyBsZXhpY2FsIGJpbmRpbmdzIHRoYXQgd291bGQgY2FwdHVyZSBKYXZhJ3MgcGFja2FnZSBxdWFsaWZpZXIgaW4gZW1pdHRlZCBjb2xsZWN0aW9uIGZhY3Rvcmllcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFZhbGlkYXRlZCBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVKYXZhVXRpbEZhY3RvcnlOYW1lcyhtb2R1bGUpIHtcbiAgLyoqXG4gICAqIFdhbGtzIG9uZSBsZXhpY2FsIGJsb2NrIHdoaWxlIHJldGFpbmluZyBvbmx5IGEgY3VycmVudGx5IHZpc2libGUgY2FwdHVyZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBCbG9jayB0byBpbnNwZWN0IGluIHNlbWFudGljIG9yZGVyLlxuICAgKiBAcGFyYW0ge3tkZXRhaWw6IHN0cmluZywgbG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSB8IHVuZGVmaW5lZH0gaW5oZXJpdGVkIC0gVmlzaWJsZSBjYXB0dXJlLlxuICAgKiBAcGFyYW0ge1wiZW50cnlcIiB8IFwiZnVuY3Rpb25cIiB8IFwiY29uc3RydWN0b3JcIiB8IFwibWV0aG9kXCJ9IG93bmVyIC0gT3duaW5nIHNjb3BlIGtpbmQuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgY29uc3QgdmFsaWRhdGVCbG9ja05hbWVzID0gKGJsb2NrLCBpbmhlcml0ZWQsIG93bmVyKSA9PiB7XG4gICAgbGV0IGNhcHR1cmUgPSBpbmhlcml0ZWRcblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiAmJiBzdGF0ZW1lbnQubmFtZSA9PSBcImphdmFcIikge1xuICAgICAgICBjYXB0dXJlID0ge1xuICAgICAgICAgIGRldGFpbDogYCR7b3duZXJ9IGxvY2FsICdqYXZhJyBjYXB0dXJlcyBqYXZhLnV0aWwgZmFjdG9yeSBzeW50YXhgLFxuICAgICAgICAgIGxvY2F0aW9uOiBzdGF0ZW1lbnQubG9jYXRpb25cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgY29uc3QgZXhwcmVzc2lvbiA9IHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5jb25kaXRpb24gOlxuICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuY29uZGl0aW9uIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQubGlzdCA6XG4gICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQubWFwIDpcbiAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIgPyBzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIgOlxuICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiID8gc3RhdGVtZW50LmV4cHJlc3Npb24gOlxuICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiID8gc3RhdGVtZW50LmV4cHJlc3Npb24gOlxuICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5leHByZXNzaW9uIDpcbiAgICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmtpbmQgPT0gXCJQcmludFN0YXRlbWVudFwiID8gc3RhdGVtZW50LmV4cHJlc3Npb24gOlxuICAgICAgICAgICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiUmFpc2VTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5lcnJvci5tZXNzYWdlIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmIChjYXB0dXJlICYmIGV4cHJlc3Npb24gJiYgKGV4cHJlc3Npb25Db250YWluc0tpbmQoZXhwcmVzc2lvbiwgXCJMaXN0TGl0ZXJhbFwiKSB8fFxuICAgICAgICBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24sIFwiTWFwTGl0ZXJhbFwiKSB8fCBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24sIFwiT3JkZXJlZE1hcExpdGVyYWxcIikgfHxcbiAgICAgICAgZXhwcmVzc2lvbkNvbnRhaW5zS2luZChleHByZXNzaW9uLCBcIk9wdGlvbmFsTm9uZVwiKSB8fFxuICAgICAgICBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24sIFwiT3B0aW9uYWxTb21lXCIpKSkge1xuICAgICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkoXCJqYXZhXCIsIGNhcHR1cmUuZGV0YWlsLCBjYXB0dXJlLmxvY2F0aW9uKVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgICB2YWxpZGF0ZUJsb2NrTmFtZXMoc3RhdGVtZW50LmNvbnNlcXVlbnQsIGNhcHR1cmUsIG93bmVyKVxuICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgdmFsaWRhdGVCbG9ja05hbWVzKHN0YXRlbWVudC5hbHRlcm5hdGUsIGNhcHR1cmUsIG93bmVyKVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIikgdmFsaWRhdGVCbG9ja05hbWVzKHN0YXRlbWVudC5ib2R5LCBjYXB0dXJlLCBvd25lcilcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIikge1xuICAgICAgICBjb25zdCBsb29wQ2FwdHVyZSA9IHN0YXRlbWVudC52YWx1ZUJpbmRpbmcubmFtZSA9PSBcImphdmFcIiA/IHtcbiAgICAgICAgICBkZXRhaWw6IGAke293bmVyfSBpdGVyYXRpb24gYmluZGluZyAnamF2YScgY2FwdHVyZXMgamF2YS51dGlsIGZhY3Rvcnkgc3ludGF4YCxcbiAgICAgICAgICBsb2NhdGlvbjogc3RhdGVtZW50LnZhbHVlQmluZGluZy5sb2NhdGlvblxuICAgICAgICB9IDogY2FwdHVyZVxuXG4gICAgICAgIHZhbGlkYXRlQmxvY2tOYW1lcyhzdGF0ZW1lbnQuYm9keSwgbG9vcENhcHR1cmUsIG93bmVyKVxuICAgICAgfVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgICAgIGNvbnN0IGNhcHR1cmVkQmluZGluZyA9IFtzdGF0ZW1lbnQua2V5QmluZGluZywgc3RhdGVtZW50LnZhbHVlQmluZGluZ10uZmluZCgoe25hbWV9KSA9PiBuYW1lID09IFwiamF2YVwiKVxuICAgICAgICBjb25zdCBsb29wQ2FwdHVyZSA9IGNhcHR1cmVkQmluZGluZyA/IHtcbiAgICAgICAgICBkZXRhaWw6IGAke293bmVyfSBpdGVyYXRpb24gYmluZGluZyAnamF2YScgY2FwdHVyZXMgamF2YS51dGlsIGZhY3Rvcnkgc3ludGF4YCxcbiAgICAgICAgICBsb2NhdGlvbjogY2FwdHVyZWRCaW5kaW5nLmxvY2F0aW9uXG4gICAgICAgIH0gOiBjYXB0dXJlXG5cbiAgICAgICAgdmFsaWRhdGVCbG9ja05hbWVzKHN0YXRlbWVudC5ib2R5LCBsb29wQ2FwdHVyZSwgb3duZXIpXG4gICAgICB9XG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgICB2YWxpZGF0ZUJsb2NrTmFtZXMoc3RhdGVtZW50LmJvZHksIGNhcHR1cmUsIG93bmVyKVxuICAgICAgICBjb25zdCBjYXRjaENhcHR1cmUgPSBzdGF0ZW1lbnQuY2F0Y2hCaW5kaW5nLm5hbWUgPT0gXCJqYXZhXCIgPyB7XG4gICAgICAgICAgZGV0YWlsOiBgJHtvd25lcn0gY2F0Y2ggYmluZGluZyAnamF2YScgY2FwdHVyZXMgamF2YS51dGlsIGZhY3Rvcnkgc3ludGF4YCxcbiAgICAgICAgICBsb2NhdGlvbjogc3RhdGVtZW50LmNhdGNoQmluZGluZy5sb2NhdGlvblxuICAgICAgICB9IDogY2FwdHVyZVxuXG4gICAgICAgIHZhbGlkYXRlQmxvY2tOYW1lcyhzdGF0ZW1lbnQuY2F0Y2hCb2R5LCBjYXRjaENhcHR1cmUsIG93bmVyKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHZhbGlkYXRlQmxvY2tOYW1lcyhtb2R1bGUuZW50cnlQb2ludC5ib2R5LCB1bmRlZmluZWQsIFwiZW50cnlcIilcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB7XG4gICAgY29uc3QgcGFyYW1ldGVyID0gZGVjbGFyYXRpb24ucGFyYW1ldGVycy5maW5kKCh7bmFtZX0pID0+IG5hbWUgPT0gXCJqYXZhXCIpXG4gICAgY29uc3QgY2FwdHVyZSA9IHBhcmFtZXRlciA/IHtcbiAgICAgIGRldGFpbDogXCJmdW5jdGlvbiBwYXJhbWV0ZXIgJ2phdmEnIGNhcHR1cmVzIGphdmEudXRpbCBmYWN0b3J5IHN5bnRheFwiLFxuICAgICAgbG9jYXRpb246IHBhcmFtZXRlci5sb2NhdGlvblxuICAgIH0gOiB1bmRlZmluZWRcblxuICAgIHZhbGlkYXRlQmxvY2tOYW1lcyhkZWNsYXJhdGlvbi5ib2R5LCBjYXB0dXJlLCBcImZ1bmN0aW9uXCIpXG4gIH1cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuY2xhc3NlcyA/PyBbXSkge1xuICAgIGNvbnN0IGNhbGxhYmxlcyA9IFtcbiAgICAgIHtib2R5OiBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5ib2R5LCBvd25lcjogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiY29uc3RydWN0b3JcIiksIHBhcmFtZXRlcnM6IGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yLnBhcmFtZXRlcnN9LFxuICAgICAgLi4uZGVjbGFyYXRpb24ubWV0aG9kcy5tYXAoKG1ldGhvZCkgPT4gKHtib2R5OiBtZXRob2QuYm9keSwgb3duZXI6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIm1ldGhvZFwiKSwgcGFyYW1ldGVyczogbWV0aG9kLnBhcmFtZXRlcnN9KSlcbiAgICBdXG5cbiAgICBmb3IgKGNvbnN0IGNhbGxhYmxlIG9mIGNhbGxhYmxlcykge1xuICAgICAgY29uc3QgcGFyYW1ldGVyID0gY2FsbGFibGUucGFyYW1ldGVycy5maW5kKCh7bmFtZX0pID0+IG5hbWUgPT0gXCJqYXZhXCIpXG4gICAgICBjb25zdCBjYXB0dXJlID0gcGFyYW1ldGVyID8ge1xuICAgICAgICBkZXRhaWw6IGAke2NhbGxhYmxlLm93bmVyfSBwYXJhbWV0ZXIgJ2phdmEnIGNhcHR1cmVzIGphdmEudXRpbCBmYWN0b3J5IHN5bnRheGAsXG4gICAgICAgIGxvY2F0aW9uOiBwYXJhbWV0ZXIubG9jYXRpb25cbiAgICAgIH0gOiB1bmRlZmluZWRcblxuICAgICAgdmFsaWRhdGVCbG9ja05hbWVzKGNhbGxhYmxlLmJvZHksIGNhcHR1cmUsIGNhbGxhYmxlLm93bmVyKVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciBhIG1vZHVsZSBjb250YWlucyBhbiBleHByZXNzaW9uIGtpbmQgdGhhdCByZXF1aXJlcyB0YXJnZXQgcnVudGltZSBzY2FmZm9sZGluZy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IG1vZHVsZSAtIFZhbGlkYXRlZC1zaGFwZSBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb25bXCJraW5kXCJdfSBraW5kIC0gU291Z2h0IGV4cHJlc3Npb24ga2luZC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBraW5kIG9jY3Vycy5cbiAqL1xuZnVuY3Rpb24gbW9kdWxlQ29udGFpbnNFeHByZXNzaW9uS2luZChtb2R1bGUsIGtpbmQpIHtcbiAgY29uc3QgY2xhc3NCbG9ja3MgPSAobW9kdWxlLmNsYXNzZXMgPz8gW10pLmZsYXRNYXAoKGRlY2xhcmF0aW9uKSA9PiBbXG4gICAgZGVjbGFyYXRpb24uY29uc3RydWN0b3IuYm9keSwgLi4uZGVjbGFyYXRpb24ubWV0aG9kcy5tYXAoKG1ldGhvZCkgPT4gbWV0aG9kLmJvZHkpXG4gIF0pXG5cbiAgcmV0dXJuIFttb2R1bGUuZW50cnlQb2ludC5ib2R5LCAuLi5tb2R1bGUuZnVuY3Rpb25zLm1hcCgoZGVjbGFyYXRpb24pID0+IGRlY2xhcmF0aW9uLmJvZHkpLCAuLi5jbGFzc0Jsb2Nrc10uc29tZSgoYmxvY2spID0+XG4gICAgYWxsU3RhdGVtZW50cyhibG9jaykuc29tZSgoc3RhdGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBleHByZXNzaW9uID0gc3RhdGVtZW50LmtpbmQgPT0gXCJJZlN0YXRlbWVudFwiID8gc3RhdGVtZW50LmNvbmRpdGlvbiA6XG4gICAgICAgIHN0YXRlbWVudC5raW5kID09IFwiV2hpbGVTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5jb25kaXRpb24gOlxuICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5saXN0IDpcbiAgICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIiA/IHN0YXRlbWVudC5tYXAgOlxuICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIiA/IHN0YXRlbWVudC5pbml0aWFsaXplciA6XG4gICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJBc3NpZ25tZW50U3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6XG4gICAgICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6XG4gICAgICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiID8gc3RhdGVtZW50LmV4cHJlc3Npb24gOlxuICAgICAgICAgICAgICBzdGF0ZW1lbnQua2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIgPyBzdGF0ZW1lbnQuZXhwcmVzc2lvbiA6XG4gICAgICAgICAgICAgICAgc3RhdGVtZW50LmtpbmQgPT0gXCJSYWlzZVN0YXRlbWVudFwiID8gc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UgOiB1bmRlZmluZWRcblxuICAgICAgcmV0dXJuIGV4cHJlc3Npb24gPyBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24sIGtpbmQpIDogZmFsc2VcbiAgICB9KSlcbn1cblxuLyoqXG4gKiBTZWFyY2hlcyBvbmUgdmFsaWRhdGVkIGV4cHJlc3Npb24gdHJlZSBmb3IgYSBzZW1hbnRpYyBraW5kLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gRXhwcmVzc2lvbiByb290LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9uW1wia2luZFwiXX0ga2luZCAtIFNvdWdodCBraW5kLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIGtpbmQgb2NjdXJzLlxuICovXG5mdW5jdGlvbiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24sIGtpbmQpIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBraW5kKSByZXR1cm4gdHJ1ZVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiVW5hcnlFeHByZXNzaW9uXCIpIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24ub3BlcmFuZCwga2luZClcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24ubGVmdCwga2luZCkgfHwgZXhwcmVzc2lvbkNvbnRhaW5zS2luZChleHByZXNzaW9uLnJpZ2h0LCBraW5kKVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSByZXR1cm4gZXhwcmVzc2lvbi5hcmd1bWVudHMuc29tZSgoYXJndW1lbnQpID0+IGV4cHJlc3Npb25Db250YWluc0tpbmQoYXJndW1lbnQsIGtpbmQpKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24ucmVjZWl2ZXIsIGtpbmQpIHx8XG4gICAgICBleHByZXNzaW9uLmFyZ3VtZW50cy5zb21lKChhcmd1bWVudCkgPT4gZXhwcmVzc2lvbkNvbnRhaW5zS2luZChhcmd1bWVudCwga2luZCkpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlJlY29yZENvbnN0cnVjdGlvblwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb24uYXJndW1lbnRzLnNvbWUoKGFyZ3VtZW50KSA9PiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGFyZ3VtZW50LCBraW5kKSlcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiIHx8IGV4cHJlc3Npb24ua2luZCA9PSBcIlByaXZhdGVGaWVsZFJlYWRcIikge1xuICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24ucmVjZWl2ZXIsIGtpbmQpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RMaXRlcmFsXCIpIHJldHVybiBleHByZXNzaW9uLmVsZW1lbnRzLnNvbWUoKGVsZW1lbnQpID0+IGV4cHJlc3Npb25Db250YWluc0tpbmQoZWxlbWVudCwga2luZCkpXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJNYXBMaXRlcmFsXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIikge1xuICAgIHJldHVybiBleHByZXNzaW9uLmVudHJpZXMuc29tZSgoZW50cnkpID0+IGV4cHJlc3Npb25Db250YWluc0tpbmQoZW50cnkua2V5LCBraW5kKSB8fCBleHByZXNzaW9uQ29udGFpbnNLaW5kKGVudHJ5LnZhbHVlLCBraW5kKSlcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdEluZGV4RXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc0tpbmQoZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBraW5kKSB8fCBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24uaW5kZXgsIGtpbmQpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24uY29sbGVjdGlvbiwga2luZCkgfHwgZXhwcmVzc2lvbkNvbnRhaW5zS2luZChleHByZXNzaW9uLmtleSwga2luZClcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNLaW5kKGV4cHJlc3Npb24uY29sbGVjdGlvbiwga2luZClcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zS2luZChleHByZXNzaW9uLnZhbHVlLCBraW5kKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxJc1ByZXNlbnRcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFVud3JhcFwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc0tpbmQoZXhwcmVzc2lvbi5vcGVyYW5kLCBraW5kKVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHBhcnNlci1iYWNrZWQgZnVuY3Rpb24tbmFtZSBsb2NhdGlvbiB3aGVuIG9uZSBzdXJ2aXZlZCBzZW1hbnRpYyBhZGFwdGF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFNlbWFudGljIGZ1bmN0aW9uIGRlY2xhcmF0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBFeGFjdCBuYW1lIG9yIGRlY2xhcmF0aW9uIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBkZWNsYXJhdGlvbk5hbWVMb2NhdGlvbihkZWNsYXJhdGlvbikge1xuICByZXR1cm4gZGVjbGFyYXRpb24uc291cmNlUHJvdmVuYW5jZT8ucmFuZ2VzLm5hbWUgPz8gZGVjbGFyYXRpb24ubG9jYXRpb25cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgcGFyc2VyLWJhY2tlZCBiaW5kaW5nLW5hbWUgbG9jYXRpb24gd2hlbiBvbmUgc3Vydml2ZWQgc2VtYW50aWMgYWRhcHRhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUGFyYW1ldGVyIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlZhbHVlQmluZGluZyB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhdGNoQmluZGluZ30gYmluZGluZyAtIFNlbWFudGljIGJpbmRpbmcuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IEV4YWN0IG5hbWUgb3IgYmluZGluZyBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmluZGluZ05hbWVMb2NhdGlvbihiaW5kaW5nKSB7XG4gIHJldHVybiBiaW5kaW5nLnNvdXJjZVByb3ZlbmFuY2U/LnJhbmdlcy5uYW1lID8/IGJpbmRpbmcubG9jYXRpb25cbn1cblxuLyoqXG4gKiBCdWlsZHMgdGhlIEphdmEgbWV0aG9kIHNpZ25hdHVyZSB1c2VkIGZvciBpbmhlcml0ZWQtaW5zdGFuY2UgY29sbGlzaW9uIGNoZWNrcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBDYW5kaWRhdGUgSmF2YSB0YXJnZXQgZnVuY3Rpb24uXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSBFbWl0dGVkIG5hbWUgYW5kIHBhcmFtZXRlciB0eXBlcyB3aGVuIGFsbCB0eXBlcyBhcmUgc3VwcG9ydGVkLlxuICovXG5mdW5jdGlvbiBlbWl0dGVkSmF2YUZ1bmN0aW9uU2lnbmF0dXJlKGRlY2xhcmF0aW9uKSB7XG4gIGNvbnN0IHBhcmFtZXRlclR5cGVzID0gW11cblxuICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBkZWNsYXJhdGlvbi5wYXJhbWV0ZXJzKSB7XG4gICAgY29uc3QgdHlwZSA9IHBhcmFtZXRlci50eXBlXG5cbiAgICBpZiAoIXR5cGUgfHwgdHlwZW9mIHR5cGUgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHR5cGUpKSByZXR1cm4gdW5kZWZpbmVkXG4gICAgY29uc3QgZW1pdHRlZCA9IHR5cGUua2luZCA9PSBcIkxpc3RUeXBlXCIgPyBcImphdmEudXRpbC5MaXN0XCIgOiB0eXBlLmtpbmQgPT0gXCJNYXBUeXBlXCIgPyBcImphdmEudXRpbC5NYXBcIiA6XG4gICAgICB0eXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJqYXZhLnV0aWwuU2VxdWVuY2VkTWFwXCIgOlxuICAgICAgdHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiID8gZW1pdFNjYWxhclR5cGUoXCJqYXZhXCIsIHR5cGUpIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoIWVtaXR0ZWQpIHJldHVybiB1bmRlZmluZWRcbiAgICBwYXJhbWV0ZXJUeXBlcy5wdXNoKGVtaXR0ZWQpXG4gIH1cblxuICByZXR1cm4gYCR7ZGVjbGFyYXRpb24ubmFtZX0oJHtwYXJhbWV0ZXJUeXBlcy5qb2luKFwiLFwiKX0pYFxufVxuXG4vKipcbiAqIFJldHVybnMgZXZlcnkgc3RhdGVtZW50IG5lc3RlZCBiZW5lYXRoIGEgYmxvY2sgaW4gc2VtYW50aWMgb3JkZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBibG9jayAtIFNlbWFudGljIGJsb2NrLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudFtdfSBTdGF0ZW1lbnRzIGluY2x1ZGluZyBuZXN0ZWQgYnJhbmNoZXMuXG4gKi9cbmZ1bmN0aW9uIGFsbFN0YXRlbWVudHMoYmxvY2spIHtcbiAgcmV0dXJuIGJsb2NrLnN0YXRlbWVudHMuZmxhdE1hcCgoc3RhdGVtZW50KSA9PiB7XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiSWZTdGF0ZW1lbnRcIikge1xuICAgICAgcmV0dXJuIFtzdGF0ZW1lbnQsIC4uLmFsbFN0YXRlbWVudHMoc3RhdGVtZW50LmNvbnNlcXVlbnQpLCAuLi4oc3RhdGVtZW50LmFsdGVybmF0ZSA/IGFsbFN0YXRlbWVudHMoc3RhdGVtZW50LmFsdGVybmF0ZSkgOiBbXSldXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiB8fCBzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIikge1xuICAgICAgcmV0dXJuIFtzdGF0ZW1lbnQsIC4uLmFsbFN0YXRlbWVudHMoc3RhdGVtZW50LmJvZHkpXVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiKSByZXR1cm4gW3N0YXRlbWVudCwgLi4uYWxsU3RhdGVtZW50cyhzdGF0ZW1lbnQuYm9keSldXG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiVHJ5U3RhdGVtZW50XCIpIHJldHVybiBbc3RhdGVtZW50LCAuLi5hbGxTdGF0ZW1lbnRzKHN0YXRlbWVudC5ib2R5KSwgLi4uYWxsU3RhdGVtZW50cyhzdGF0ZW1lbnQuY2F0Y2hCb2R5KV1cblxuICAgIHJldHVybiBbc3RhdGVtZW50XVxuICB9KVxufVxuXG4vKipcbiAqIEluZGV4ZXMgZXhhY3QgbG9vcCBpZGVudGl0aWVzIGJlZm9yZSByZWN1cnNpdmUgdGFyZ2V0IHZhbGlkYXRpb24gc28gY3Jvc3MtZnVuY3Rpb24gdGFyZ2V0cyBmYWlsIGRldGVybWluaXN0aWNhbGx5LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gbW9kdWxlIC0gQ2FuZGlkYXRlIHNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBvYmplY3Q+fSBMb29wIG93bmVyIGJ5IG1vZHVsZS1sb2NhbCBpZGVudGl0eS5cbiAqL1xuZnVuY3Rpb24gY29sbGVjdExvb3BPd25lcnMobW9kdWxlLCBsYW5ndWFnZSkge1xuICBjb25zdCBvd25lcnMgPSBuZXcgTWFwKClcbiAgY29uc3QgY2xhc3NPd25lcnMgPSAobW9kdWxlLmNsYXNzZXMgPz8gW10pLmZsYXRNYXAoKGRlY2xhcmF0aW9uKSA9PiBbZGVjbGFyYXRpb24uY29uc3RydWN0b3IsIC4uLmRlY2xhcmF0aW9uLm1ldGhvZHNdKVxuXG4gIGZvciAoY29uc3Qgb3duZXIgb2YgWy4uLmNsYXNzT3duZXJzLCAuLi5tb2R1bGUuZnVuY3Rpb25zLCBtb2R1bGUuZW50cnlQb2ludF0pIHtcbiAgICBpZiAob3duZXIgJiYgdHlwZW9mIG93bmVyID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkob3duZXIpKSB2aXNpdChSZWZsZWN0LmdldChvd25lciwgXCJib2R5XCIpLCBvd25lcilcbiAgfVxuXG4gIHJldHVybiBvd25lcnNcblxuICAvKipcbiAgICogVmlzaXRzIGxvb3AgY29udGFpbmVycyB3aGlsZSBib3VuZGluZyBtYWxmb3JtZWQgY3ljbGVzLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGJsb2NrIC0gQ2FuZGlkYXRlIGJsb2NrLlxuICAgKiBAcGFyYW0ge29iamVjdH0gb3duZXIgLSBFbmNsb3NpbmcgZnVuY3Rpb24gb3IgZW50cnkgcG9pbnQuXG4gICAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFthY3RpdmVdIC0gQmxvY2tzIG9uIHRoZSBhY3RpdmUgcmVjdXJzaXZlIHBhdGguXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgZnVuY3Rpb24gdmlzaXQoYmxvY2ssIG93bmVyLCBhY3RpdmUgPSBuZXcgU2V0KCkpIHtcbiAgICBpZiAoIWJsb2NrIHx8IHR5cGVvZiBibG9jayAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoYmxvY2spIHx8IGFjdGl2ZS5oYXMoYmxvY2spKSByZXR1cm5cbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gUmVmbGVjdC5nZXQoYmxvY2ssIFwic3RhdGVtZW50c1wiKVxuXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHN0YXRlbWVudHMpKSByZXR1cm5cbiAgICBjb25zdCBwYXRoID0gbmV3IFNldChhY3RpdmUpXG5cbiAgICBwYXRoLmFkZChibG9jaylcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBzdGF0ZW1lbnRzKSB7XG4gICAgICBpZiAoIXN0YXRlbWVudCB8fCB0eXBlb2Ygc3RhdGVtZW50ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShzdGF0ZW1lbnQpKSBjb250aW51ZVxuICAgICAgY29uc3Qga2luZCA9IFN0cmluZyhSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwia2luZFwiKSlcblxuICAgICAgaWYgKFtcIkZvckVhY2hTdGF0ZW1lbnRcIiwgXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIsIFwiV2hpbGVTdGF0ZW1lbnRcIl0uaW5jbHVkZXMoa2luZCkpIHtcbiAgICAgICAgY29uc3QgaWQgPSBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiaWRcIilcbiAgICAgICAgY29uc3QgbG9jYXRpb24gPSBkaWFnbm9zdGljTG9jYXRpb24oUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImxvY2F0aW9uXCIpLCBSZWZsZWN0LmdldChibG9jaywgXCJsb2NhdGlvblwiKSlcblxuICAgICAgICBpZiAodHlwZW9mIGlkICE9IFwic3RyaW5nXCIgfHwgIS9ebG9vcDpbMC05XSskL3UudGVzdChpZCkpIGNvbnRpbnVlXG4gICAgICAgIGlmIChvd25lcnMuaGFzKGlkKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImR1cGxpY2F0ZSBvciBpbnZhbGlkIGxvb3AgaWRlbnRpdHlcIiwgbG9jYXRpb24pXG4gICAgICAgIG93bmVycy5zZXQoaWQsIG93bmVyKVxuICAgICAgICB2aXNpdChSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiYm9keVwiKSwgb3duZXIsIHBhdGgpXG4gICAgICB9IGVsc2UgaWYgKGtpbmQgPT0gXCJJZlN0YXRlbWVudFwiKSB7XG4gICAgICAgIHZpc2l0KFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJjb25zZXF1ZW50XCIpLCBvd25lciwgcGF0aClcbiAgICAgICAgdmlzaXQoUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImFsdGVybmF0ZVwiKSwgb3duZXIsIHBhdGgpXG4gICAgICB9IGVsc2UgaWYgKGtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgICAgICB2aXNpdChSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiYm9keVwiKSwgb3duZXIsIHBhdGgpXG4gICAgICAgIHZpc2l0KFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJjYXRjaEJvZHlcIiksIG93bmVyLCBwYXRoKVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgY29tcGxldGUgc2VtYW50aWMgYmxvY2sgYmVmb3JlIGVtaXNzaW9uLlxuICogQHBhcmFtIHt1bmtub3dufSBibG9jayAtIENhbmRpZGF0ZSBibG9jay5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2Ugb3IgYmluYXJ5IHRhcmdldC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9IG93bmVyTG9jYXRpb24gLSBFbmNsb3NpbmcgbG9jYXRpb24uXG4gKiBAcGFyYW0ge3thY3RpdmU6IChpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoU3RhdGVtZW50IHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRm9yRWFjaE1hcFN0YXRlbWVudCB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLldoaWxlU3RhdGVtZW50KVtdLCBvd25lcjogb2JqZWN0LCBvd25lcnM6IE1hcDxzdHJpbmcsIG9iamVjdD59fSBsb29wQ29udGV4dCAtIEFjdGl2ZSBsb29wcyBhbmQgdGhlaXIgbGV4aWNhbCBvd25lci5cbiAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFthY3RpdmVQYXRoXSAtIEJsb2NrcyBvbiB0aGUgYWN0aXZlIHJlY3Vyc2l2ZSBwYXRoLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gW2V4dGVybmFsRGVjbGFyYXRpb25JZHNdIC0gUmVzb2x2ZWQgZGVjbGFyYXRpb25zIHdob3NlIHNvdXJjZSBzcGVsbGluZyBpcyB0YXJnZXQtaW5kZXBlbmRlbnQuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVCbG9jayhibG9jaywgbGFuZ3VhZ2UsIG93bmVyTG9jYXRpb24sIGxvb3BDb250ZXh0LCBhY3RpdmVQYXRoID0gbmV3IFNldCgpLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzID0gbmV3IFNldCgpKSB7XG4gIGlmICghYmxvY2sgfHwgdHlwZW9mIGJsb2NrICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShibG9jaykpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBibG9ja1wiLCBvd25lckxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKGJsb2NrKVxuICBjb25zdCBsb2NhdGlvbiA9IGRpYWdub3N0aWNMb2NhdGlvbihjYW5kaWRhdGUubG9jYXRpb24sIG93bmVyTG9jYXRpb24pXG5cbiAgaWYgKGFjdGl2ZVBhdGguaGFzKGNhbmRpZGF0ZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJjeWNsaWMgYmxvY2tcIiwgbG9jYXRpb24pXG4gIGlmIChjYW5kaWRhdGUua2luZCAhPSBcIkJsb2NrXCIpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYGJsb2NrICR7U3RyaW5nKFJlZmxlY3QuZ2V0KGJsb2NrLCBcImtpbmRcIikpfWAsIGxvY2F0aW9uKVxuICBpZiAoIUFycmF5LmlzQXJyYXkoY2FuZGlkYXRlLnN0YXRlbWVudHMpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIGJsb2NrIHN0YXRlbWVudHNcIiwgbG9jYXRpb24pXG4gIGNvbnN0IGJsb2NrUGF0aCA9IG5ldyBTZXQoYWN0aXZlUGF0aClcblxuICBibG9ja1BhdGguYWRkKGNhbmRpZGF0ZSlcbiAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgY2FuZGlkYXRlLnN0YXRlbWVudHMpIHtcbiAgICB2YWxpZGF0ZVN0YXRlbWVudChzdGF0ZW1lbnQsIGxhbmd1YWdlLCBsb2NhdGlvbiwgbG9vcENvbnRleHQsIGJsb2NrUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgfVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyBvbmUgc3VwcG9ydGVkIHN0YXRlbWVudCByZWN1cnNpdmVseS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gc3RhdGVtZW50IC0gQ2FuZGlkYXRlIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgbGFuZ3VhZ2Ugb3IgYmluYXJ5IHRhcmdldC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9IG93bmVyTG9jYXRpb24gLSBFbmNsb3NpbmcgYm9keSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7e2FjdGl2ZTogKGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZvckVhY2hTdGF0ZW1lbnQgfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoTWFwU3RhdGVtZW50IHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuV2hpbGVTdGF0ZW1lbnQpW10sIG93bmVyOiBvYmplY3QsIG93bmVyczogTWFwPHN0cmluZywgb2JqZWN0Pn19IGxvb3BDb250ZXh0IC0gQWN0aXZlIGxvb3BzIGFuZCB0aGVpciBsZXhpY2FsIG93bmVyLlxuICogQHBhcmFtIHtTZXQ8b2JqZWN0Pn0gW2FjdGl2ZVBhdGhdIC0gQWN0aXZlIGJsb2NrIGNvbnRhaW5lcnMuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSBbZXh0ZXJuYWxEZWNsYXJhdGlvbklkc10gLSBSZXNvbHZlZCBkZWNsYXJhdGlvbnMgd2hvc2Ugc291cmNlIHNwZWxsaW5nIGlzIHRhcmdldC1pbmRlcGVuZGVudC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVN0YXRlbWVudChzdGF0ZW1lbnQsIGxhbmd1YWdlLCBvd25lckxvY2F0aW9uLCBsb29wQ29udGV4dCwgYWN0aXZlUGF0aCA9IG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcyA9IG5ldyBTZXQoKSkge1xuICBpZiAoIXN0YXRlbWVudCB8fCB0eXBlb2Ygc3RhdGVtZW50ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShzdGF0ZW1lbnQpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgc3RhdGVtZW50XCIsIG93bmVyTG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBraW5kID0gUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImtpbmRcIilcbiAgY29uc3Qgb3duTG9jYXRpb24gPSBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwibG9jYXRpb25cIilcbiAgY29uc3QgbG9jYXRpb24gPSBkaWFnbm9zdGljTG9jYXRpb24ob3duTG9jYXRpb24sIG93bmVyTG9jYXRpb24pXG5cbiAgaWYgKHR5cGVvZiBraW5kICE9IFwic3RyaW5nXCIpIHJldHVybiB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIHN0YXRlbWVudFwiLCBsb2NhdGlvbilcbiAgaWYgKGtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxEZWNsYXJhdGlvbn0gKi8gKHN0YXRlbWVudClcblxuICAgIGlmICh0eXBlb2YgZGVjbGFyYXRpb24ubXV0YWJsZSAhPSBcImJvb2xlYW5cIikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImxvY2FsIGRlY2xhcmF0aW9uIHdpdGggaW52YWxpZCBtdXRhYmlsaXR5XCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICB2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyKGxhbmd1YWdlLCBkZWNsYXJhdGlvbi5uYW1lLCBcImxvY2FsXCIsIGxvY2F0aW9uKVxuICAgIGlmIChkZWNsYXJhdGlvbi50eXBlPy5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIiAmJiBkZWNsYXJhdGlvbi5pbml0aWFsaXplcj8ua2luZCAhPSBcIk9yZGVyZWRNYXBMaXRlcmFsXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJvcmRlcmVkLW1hcCBsb2NhbCByZXF1aXJlcyBhIGRpcmVjdCBsaXRlcmFsIGluaXRpYWxpemVyXCIsXG4gICAgICAgIGRpYWdub3N0aWNMb2NhdGlvbihkZWNsYXJhdGlvbi5pbml0aWFsaXplcj8ubG9jYXRpb24sIGxvY2F0aW9uKSlcbiAgICB9XG4gICAgaWYgKGRlY2xhcmF0aW9uLmluaXRpYWxpemVyPy5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIiAmJiBkZWNsYXJhdGlvbi5tdXRhYmxlICE9PSBmYWxzZSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm9yZGVyZWQtbWFwIGxvY2FsIG11c3QgYmUgaW1tdXRhYmxlXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oZGVjbGFyYXRpb24uaW5pdGlhbGl6ZXIsIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcyxcbiAgICAgIGxhbmd1YWdlID09IFwiamF2YVwiICYmIGRlY2xhcmF0aW9uLmluaXRpYWxpemVyPy5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIilcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoa2luZCA9PSBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGFzc2lnbm1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkFzc2lnbm1lbnRTdGF0ZW1lbnR9ICovIChzdGF0ZW1lbnQpXG5cbiAgICB2YWxpZGF0ZUFzc2lnbm1lbnRUYXJnZXQoYXNzaWdubWVudC50YXJnZXQsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oYXNzaWdubWVudC5leHByZXNzaW9uLCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBuZXcgU2V0KCksIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGtpbmQgPT0gXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiKSB7XG4gICAgY29uc3QgYXNzaWdubWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUHJpdmF0ZUZpZWxkV3JpdGVTdGF0ZW1lbnR9ICovIChzdGF0ZW1lbnQpXG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMoYXNzaWdubWVudCkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICBpZiAoZmllbGRzICE9IFwiZXhwcmVzc2lvbixmaWVsZCxraW5kLGxvY2F0aW9uLHJlY2VpdmVyXCIgfHwgdHlwZW9mIGFzc2lnbm1lbnQuZmllbGQgIT0gXCJzdHJpbmdcIiB8fFxuICAgICAgYXNzaWdubWVudC5yZWNlaXZlcj8ua2luZCAhPSBcIlJlY2VpdmVyRXhwcmVzc2lvblwiKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIHByaXZhdGUgZmllbGQgcmVjZWl2ZXIgb3IgcHJpdmF0ZSBmaWVsZCBpZGVudGl0eVwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVFeHByZXNzaW9uKGFzc2lnbm1lbnQucmVjZWl2ZXIsIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oYXNzaWdubWVudC5leHByZXNzaW9uLCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBuZXcgU2V0KCksIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiZXhwcmVzc2lvblwiKVxuXG4gICAgaWYgKGV4cHJlc3Npb24gIT09IHVuZGVmaW5lZCkgdmFsaWRhdGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJydWJ5XCIgJiYgbG9vcENvbnRleHQuYWN0aXZlLnNvbWUoKHtraW5kfSkgPT4ga2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIiB8fCBraW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInJldHVybiBmcm9tIGFuIGl0ZXJhdGlvbiBib2R5XCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoa2luZCA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIikge1xuICAgIGlmICghdGFzazAwNUxhbmd1YWdlcy5oYXMobGFuZ3VhZ2UpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMDUgdm9pZCBjYWxsIGV4cHJlc3Npb24gc3RhdGVtZW50XCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBleHByZXNzaW9uID0gUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImV4cHJlc3Npb25cIilcblxuICAgIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiIHx8XG4gICAgICAhW1wiQ2FsbEV4cHJlc3Npb25cIiwgXCJFZmZlY3RDYWxsRXhwcmVzc2lvblwiLCBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCJdLmluY2x1ZGVzKFN0cmluZyhSZWZsZWN0LmdldChleHByZXNzaW9uLCBcImtpbmRcIikpKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImV4cHJlc3Npb24gc3RhdGVtZW50IG90aGVyIHRoYW4gYSBkaXJlY3Qgb3IgcmVjZWl2ZXIgY2FsbFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoa2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIpIHtcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImV4cHJlc3Npb25cIiksIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoa2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICBjb25zdCBicmFuY2ggPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLklmU3RhdGVtZW50fSAqLyAoc3RhdGVtZW50KVxuXG4gICAgdmFsaWRhdGVFeHByZXNzaW9uKGJyYW5jaC5jb25kaXRpb24sIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB2YWxpZGF0ZUJsb2NrKGJyYW5jaC5jb25zZXF1ZW50LCBsYW5ndWFnZSwgbG9jYXRpb24sIGxvb3BDb250ZXh0LCBhY3RpdmVQYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIGlmIChPYmplY3QuaGFzT3duKGJyYW5jaCwgXCJhbHRlcm5hdGVcIikpIHtcbiAgICAgIHZhbGlkYXRlQmxvY2soYnJhbmNoLmFsdGVybmF0ZSwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBsb29wQ29udGV4dCwgYWN0aXZlUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGtpbmQgPT0gXCJCcmVha1N0YXRlbWVudFwiIHx8IGtpbmQgPT0gXCJDb250aW51ZVN0YXRlbWVudFwiKSB7XG4gICAgaWYgKCF0YXNrMDA4TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwOCBvcmRlcmVkIGxpc3QgaXRlcmF0aW9uXCIsIGxvY2F0aW9uKVxuICAgIHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKG93bkxvY2F0aW9uLCBsYW5ndWFnZSwgYCR7a2luZH0gbG9jYXRpb25gLCBvd25lckxvY2F0aW9uKVxuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKC8qKiBAdHlwZSB7b2JqZWN0fSAqLyAoc3RhdGVtZW50KSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICBpZiAoZmllbGRzICE9IFwia2luZCxsb2NhdGlvbix0YXJnZXRMb29wSWRcIikgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgbWFsZm9ybWVkICR7a2luZH1gLCBsb2NhdGlvbilcbiAgICBjb25zdCB0YXJnZXRMb29wSWQgPSBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwidGFyZ2V0TG9vcElkXCIpXG4gICAgY29uc3QgbmVhcmVzdCA9IGxvb3BDb250ZXh0LmFjdGl2ZS5hdCgtMSlcblxuICAgIGlmICghbmVhcmVzdCkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgJHtraW5kID09IFwiQnJlYWtTdGF0ZW1lbnRcIiA/IFwiYnJlYWtcIiA6IFwiY29udGludWVcIn0gb3V0c2lkZSBhIGxvb3BgLCBsb2NhdGlvbilcbiAgICBpZiAodHlwZW9mIHRhcmdldExvb3BJZCAhPSBcInN0cmluZ1wiIHx8ICFsb29wQ29udGV4dC5vd25lcnMuaGFzKHRhcmdldExvb3BJZCkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJpbnZhbGlkIGxvb3AgY29udHJvbCB0YXJnZXQgaWRlbnRpdHlcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChsb29wQ29udGV4dC5vd25lcnMuZ2V0KHRhcmdldExvb3BJZCkgIT09IGxvb3BDb250ZXh0Lm93bmVyKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibG9vcCBjb250cm9sIHRhcmdldCBjcm9zc2VzIGEgZnVuY3Rpb24gYm91bmRhcnlcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICh0YXJnZXRMb29wSWQgIT0gbmVhcmVzdC5pZCkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImxvb3AgY29udHJvbCBtdXN0IHRhcmdldCB0aGUgbmVhcmVzdCBlbmNsb3NpbmcgbG9vcFwiLCBsb2NhdGlvbilcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoa2luZCA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHtcbiAgICBpZiAoIXRhc2swMzJMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDMyIGNvbmRpdGlvbi1jb250cm9sbGVkIGxvb3BcIiwgbG9jYXRpb24pXG4gICAgY29uc3QgbG9vcExvY2F0aW9uID0gcmVxdWlyZVNlbWFudGljTG9jYXRpb24ob3duTG9jYXRpb24sIGxhbmd1YWdlLCBcIldoaWxlU3RhdGVtZW50IGxvY2F0aW9uXCIsIG93bmVyTG9jYXRpb24pXG4gICAgY29uc3QgbG9vcCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuV2hpbGVTdGF0ZW1lbnR9ICovIChzdGF0ZW1lbnQpXG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMobG9vcCkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICBpZiAoZmllbGRzICE9IFwiYm9keSxjb25kaXRpb24saWQsa2luZCxsb2NhdGlvblwiKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIFdoaWxlU3RhdGVtZW50XCIsIGxvb3BMb2NhdGlvbilcbiAgICBpZiAodHlwZW9mIGxvb3AuaWQgIT0gXCJzdHJpbmdcIiB8fCAhL15sb29wOlswLTldKyQvdS50ZXN0KGxvb3AuaWQpIHx8IGxvb3BDb250ZXh0Lm93bmVycy5nZXQobG9vcC5pZCkgIT09IGxvb3BDb250ZXh0Lm93bmVyKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiZHVwbGljYXRlIG9yIGludmFsaWQgbG9vcCBpZGVudGl0eVwiLCBsb29wTG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghbG9vcC5jb25kaXRpb24gfHwgdHlwZW9mIGxvb3AuY29uZGl0aW9uICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShsb29wLmNvbmRpdGlvbikpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgY29uZGl0aW9uLWNvbnRyb2xsZWQgbG9vcCBjb25kaXRpb25cIiwgbG9vcExvY2F0aW9uKVxuICAgIH1cbiAgICByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihSZWZsZWN0LmdldChsb29wLmNvbmRpdGlvbiwgXCJsb2NhdGlvblwiKSwgbGFuZ3VhZ2UsIFwiY29uZGl0aW9uLWNvbnRyb2xsZWQgbG9vcCBjb25kaXRpb24gbG9jYXRpb25cIiwgbG9vcExvY2F0aW9uKVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihsb29wLmNvbmRpdGlvbiwgbGFuZ3VhZ2UsIGxvb3BMb2NhdGlvbiwgZmFsc2UsIG5ldyBTZXQoKSwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICBpZiAoIWxvb3AuYm9keSB8fCB0eXBlb2YgbG9vcC5ib2R5ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShsb29wLmJvZHkpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIGNvbmRpdGlvbi1jb250cm9sbGVkIGxvb3AgYm9keVwiLCBsb29wTG9jYXRpb24pXG4gICAgfVxuICAgIHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKFJlZmxlY3QuZ2V0KGxvb3AuYm9keSwgXCJsb2NhdGlvblwiKSwgbGFuZ3VhZ2UsIFwiY29uZGl0aW9uLWNvbnRyb2xsZWQgbG9vcCBib2R5IGxvY2F0aW9uXCIsIGxvb3BMb2NhdGlvbilcbiAgICB2YWxpZGF0ZUJsb2NrKGxvb3AuYm9keSwgbGFuZ3VhZ2UsIGxvb3BMb2NhdGlvbixcbiAgICAgIHthY3RpdmU6IFsuLi5sb29wQ29udGV4dC5hY3RpdmUsIGxvb3BdLCBvd25lcjogbG9vcENvbnRleHQub3duZXIsIG93bmVyczogbG9vcENvbnRleHQub3duZXJzfSwgYWN0aXZlUGF0aCxcbiAgICAgIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGtpbmQgPT0gXCJGb3JFYWNoU3RhdGVtZW50XCIpIHtcbiAgICBpZiAoIXRhc2swMDhMYW5ndWFnZXMuaGFzKGxhbmd1YWdlKSkgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIlRhc2sgMDA4IG9yZGVyZWQgbGlzdCBpdGVyYXRpb25cIiwgbG9jYXRpb24pXG4gICAgY29uc3QgbG9vcExvY2F0aW9uID0gcmVxdWlyZVNlbWFudGljTG9jYXRpb24ob3duTG9jYXRpb24sIGxhbmd1YWdlLCBcIkZvckVhY2hTdGF0ZW1lbnQgbG9jYXRpb25cIiwgb3duZXJMb2NhdGlvbilcbiAgICBjb25zdCBsb29wID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoU3RhdGVtZW50fSAqLyAoc3RhdGVtZW50KVxuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKGxvb3ApLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuXG4gICAgaWYgKGZpZWxkcyAhPSBcImJvZHksaWQsa2luZCxsaXN0LGxvY2F0aW9uLHZhbHVlQmluZGluZ1wiKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIEZvckVhY2hTdGF0ZW1lbnRcIiwgbG9vcExvY2F0aW9uKVxuICAgIGlmICh0eXBlb2YgbG9vcC5pZCAhPSBcInN0cmluZ1wiIHx8ICEvXmxvb3A6WzAtOV0rJC91LnRlc3QobG9vcC5pZCkgfHwgbG9vcENvbnRleHQub3duZXJzLmdldChsb29wLmlkKSAhPT0gbG9vcENvbnRleHQub3duZXIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJkdXBsaWNhdGUgb3IgaW52YWxpZCBsb29wIGlkZW50aXR5XCIsIGxvb3BMb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCFsb29wLmxpc3QgfHwgdHlwZW9mIGxvb3AubGlzdCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkobG9vcC5saXN0KSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBpdGVyYXRpb24gY29sbGVjdGlvblwiLCBsb29wTG9jYXRpb24pXG4gICAgfVxuICAgIHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKFJlZmxlY3QuZ2V0KGxvb3AubGlzdCwgXCJsb2NhdGlvblwiKSwgbGFuZ3VhZ2UsIFwiaXRlcmF0aW9uIGNvbGxlY3Rpb24gbG9jYXRpb25cIiwgbG9vcExvY2F0aW9uKVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihsb29wLmxpc3QsIGxhbmd1YWdlLCBsb29wTG9jYXRpb24sIGZhbHNlLCBuZXcgU2V0KCksIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgaWYgKCFsb29wLnZhbHVlQmluZGluZyB8fCB0eXBlb2YgbG9vcC52YWx1ZUJpbmRpbmcgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGxvb3AudmFsdWVCaW5kaW5nKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBpdGVyYXRpb24gYmluZGluZ1wiLCBsb29wTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IGJpbmRpbmcgPSBsb29wLnZhbHVlQmluZGluZ1xuICAgIGNvbnN0IGJpbmRpbmdMb2NhdGlvbiA9IHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKFJlZmxlY3QuZ2V0KGJpbmRpbmcsIFwibG9jYXRpb25cIiksIGxhbmd1YWdlLCBcIml0ZXJhdGlvbiBiaW5kaW5nIGxvY2F0aW9uXCIsIGxvb3BMb2NhdGlvbilcbiAgICBjb25zdCBiaW5kaW5nRmllbGRzID0gT2JqZWN0LmtleXMoYmluZGluZykuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICBpZiAoYmluZGluZy5raW5kICE9IFwiVmFsdWVCaW5kaW5nXCIgfHwgYmluZGluZ0ZpZWxkcyAhPSBcImtpbmQsbG9jYXRpb24sbXV0YWJsZSxuYW1lLHR5cGVcIikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBpdGVyYXRpb24gYmluZGluZ1wiLCBiaW5kaW5nTG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChiaW5kaW5nLm11dGFibGUgIT09IGZhbHNlKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibXV0YWJsZSBpdGVyYXRpb24gYmluZGluZ1wiLCBiaW5kaW5nTG9jYXRpb24pXG4gICAgdmFsaWRhdGVUYXJnZXRCaW5kaW5nSWRlbnRpZmllcihsYW5ndWFnZSwgYmluZGluZy5uYW1lLCBcIml0ZXJhdGlvbiBiaW5kaW5nXCIsIGJpbmRpbmdMb2NhdGlvbilcbiAgICBpZiAoIWxvb3AuYm9keSB8fCB0eXBlb2YgbG9vcC5ib2R5ICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShsb29wLmJvZHkpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIGl0ZXJhdGlvbiBib2R5XCIsIGxvb3BMb2NhdGlvbilcbiAgICB9XG4gICAgcmVxdWlyZVNlbWFudGljTG9jYXRpb24oUmVmbGVjdC5nZXQobG9vcC5ib2R5LCBcImxvY2F0aW9uXCIpLCBsYW5ndWFnZSwgXCJpdGVyYXRpb24gYm9keSBsb2NhdGlvblwiLCBsb29wTG9jYXRpb24pXG4gICAgdmFsaWRhdGVCbG9jayhsb29wLmJvZHksIGxhbmd1YWdlLCBsb29wTG9jYXRpb24sXG4gICAgICB7YWN0aXZlOiBbLi4ubG9vcENvbnRleHQuYWN0aXZlLCBsb29wXSwgb3duZXI6IGxvb3BDb250ZXh0Lm93bmVyLCBvd25lcnM6IGxvb3BDb250ZXh0Lm93bmVyc30sIGFjdGl2ZVBhdGgsXG4gICAgICBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChraW5kID09IFwiRm9yRWFjaE1hcFN0YXRlbWVudFwiKSB7XG4gICAgaWYgKCF0YXNrMDE0TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAxNCBvcmRlcmVkLW1hcCBpdGVyYXRpb25cIiwgbG9jYXRpb24pXG4gICAgY29uc3QgbG9vcExvY2F0aW9uID0gcmVxdWlyZVNlbWFudGljTG9jYXRpb24ob3duTG9jYXRpb24sIGxhbmd1YWdlLCBcIkZvckVhY2hNYXBTdGF0ZW1lbnQgbG9jYXRpb25cIiwgb3duZXJMb2NhdGlvbilcbiAgICBjb25zdCBsb29wID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoTWFwU3RhdGVtZW50fSAqLyAoc3RhdGVtZW50KVxuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKGxvb3ApLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuXG4gICAgaWYgKGZpZWxkcyAhPSBcImJvZHksaWQsa2V5QmluZGluZyxraW5kLGxvY2F0aW9uLG1hcCx2YWx1ZUJpbmRpbmdcIikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBGb3JFYWNoTWFwU3RhdGVtZW50XCIsIGxvb3BMb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBsb29wLmlkICE9IFwic3RyaW5nXCIgfHwgIS9ebG9vcDpbMC05XSskL3UudGVzdChsb29wLmlkKSB8fCBsb29wQ29udGV4dC5vd25lcnMuZ2V0KGxvb3AuaWQpICE9PSBsb29wQ29udGV4dC5vd25lcikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImR1cGxpY2F0ZSBvciBpbnZhbGlkIGxvb3AgaWRlbnRpdHlcIiwgbG9vcExvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoIWxvb3AubWFwIHx8IHR5cGVvZiBsb29wLm1hcCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkobG9vcC5tYXApKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIG9yZGVyZWQtbWFwIGl0ZXJhdGlvbiBjb2xsZWN0aW9uXCIsIGxvb3BMb2NhdGlvbilcbiAgICB9XG4gICAgcmVxdWlyZVNlbWFudGljTG9jYXRpb24oUmVmbGVjdC5nZXQobG9vcC5tYXAsIFwibG9jYXRpb25cIiksIGxhbmd1YWdlLCBcIm9yZGVyZWQtbWFwIGl0ZXJhdGlvbiBjb2xsZWN0aW9uIGxvY2F0aW9uXCIsIGxvb3BMb2NhdGlvbilcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24obG9vcC5tYXAsIGxhbmd1YWdlLCBsb29wTG9jYXRpb24sIGZhbHNlLCBuZXcgU2V0KCksIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgZm9yIChjb25zdCBbcm9sZSwgYmluZGluZ10gb2YgW1tcImtleVwiLCBsb29wLmtleUJpbmRpbmddLCBbXCJ2YWx1ZVwiLCBsb29wLnZhbHVlQmluZGluZ11dKSB7XG4gICAgICBpZiAoIWJpbmRpbmcgfHwgdHlwZW9mIGJpbmRpbmcgIT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGJpbmRpbmcpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYG1pc3Npbmcgb3IgaW52YWxpZCBtYXAgaXRlcmF0aW9uICR7cm9sZX0gYmluZGluZ2AsIGxvb3BMb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGNvbnN0IGJpbmRpbmdMb2NhdGlvbiA9IHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKGJpbmRpbmcubG9jYXRpb24sIGxhbmd1YWdlLCBgbWFwIGl0ZXJhdGlvbiAke3JvbGV9IGJpbmRpbmcgbG9jYXRpb25gLCBsb29wTG9jYXRpb24pXG4gICAgICBjb25zdCBiaW5kaW5nRmllbGRzID0gT2JqZWN0LmtleXMoYmluZGluZykuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICAgIGlmIChiaW5kaW5nLmtpbmQgIT0gXCJWYWx1ZUJpbmRpbmdcIiB8fCBiaW5kaW5nRmllbGRzICE9IFwia2luZCxsb2NhdGlvbixtdXRhYmxlLG5hbWUsdHlwZVwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYG1hbGZvcm1lZCBtYXAgaXRlcmF0aW9uICR7cm9sZX0gYmluZGluZ2AsIGJpbmRpbmdMb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGlmIChiaW5kaW5nLm11dGFibGUgIT09IGZhbHNlKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiTWFwIGl0ZXJhdGlvbiBiaW5kaW5ncyBtdXN0IGJlIGltbXV0YWJsZVwiLCBiaW5kaW5nTG9jYXRpb24pXG4gICAgICB2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyKGxhbmd1YWdlLCBiaW5kaW5nLm5hbWUsIGBtYXAgaXRlcmF0aW9uICR7cm9sZX0gYmluZGluZ2AsIGJpbmRpbmdMb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCFsb29wLmJvZHkgfHwgdHlwZW9mIGxvb3AuYm9keSAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkobG9vcC5ib2R5KSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBtYXAgaXRlcmF0aW9uIGJvZHlcIiwgbG9vcExvY2F0aW9uKVxuICAgIH1cbiAgICByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihSZWZsZWN0LmdldChsb29wLmJvZHksIFwibG9jYXRpb25cIiksIGxhbmd1YWdlLCBcIm1hcCBpdGVyYXRpb24gYm9keSBsb2NhdGlvblwiLCBsb29wTG9jYXRpb24pXG4gICAgdmFsaWRhdGVCbG9jayhsb29wLmJvZHksIGxhbmd1YWdlLCBsb29wTG9jYXRpb24sXG4gICAgICB7YWN0aXZlOiBbLi4ubG9vcENvbnRleHQuYWN0aXZlLCBsb29wXSwgb3duZXI6IGxvb3BDb250ZXh0Lm93bmVyLCBvd25lcnM6IGxvb3BDb250ZXh0Lm93bmVyc30sIGFjdGl2ZVBhdGgsXG4gICAgICBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChraW5kID09IFwiUmFpc2VTdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKC8qKiBAdHlwZSB7b2JqZWN0fSAqLyAoc3RhdGVtZW50KSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG4gICAgY29uc3QgcmFpc2VkID0gUmVmbGVjdC5nZXQoc3RhdGVtZW50LCBcImVycm9yXCIpXG4gICAgY29uc3QgcmFpc2VMb2NhdGlvbiA9IHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKG93bkxvY2F0aW9uLCBsYW5ndWFnZSwgXCJSYWlzZVN0YXRlbWVudCBsb2NhdGlvblwiLCBvd25lckxvY2F0aW9uKVxuICAgIGNvbnN0IGNvbnN0cnVjdGlvbkZpZWxkcyA9IHJhaXNlZCAmJiB0eXBlb2YgcmFpc2VkID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkocmFpc2VkKVxuICAgICAgPyBPYmplY3Qua2V5cyhyYWlzZWQpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSA6IFwiXCJcblxuICAgIGlmIChmaWVsZHMgIT0gXCJlcnJvcixraW5kLGxvY2F0aW9uXCIgfHwgIXJhaXNlZCB8fCB0eXBlb2YgcmFpc2VkICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShyYWlzZWQpIHx8XG4gICAgICByYWlzZWQua2luZCAhPSBcIkVycm9yQ29uc3RydWN0aW9uXCIgfHwgY29uc3RydWN0aW9uRmllbGRzICE9IFwiZXJyb3Isa2luZCxsb2NhdGlvbixtZXNzYWdlXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgUmFpc2VTdGF0ZW1lbnRcIiwgcmFpc2VMb2NhdGlvbilcbiAgICB9XG4gICAgcmVxdWlyZVNlbWFudGljTG9jYXRpb24ocmFpc2VkLmxvY2F0aW9uLCBsYW5ndWFnZSwgXCJlcnJvciBjb25zdHJ1Y3Rpb24gbG9jYXRpb25cIiwgcmFpc2VMb2NhdGlvbilcbiAgICB2YWxpZGF0ZUVycm9yVHlwZVNoYXBlKHJhaXNlZC5lcnJvciwgbGFuZ3VhZ2UsIHJhaXNlZC5sb2NhdGlvbilcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24ocmFpc2VkLm1lc3NhZ2UsIGxhbmd1YWdlLCByYWlzZWQubG9jYXRpb24sIGZhbHNlLCBuZXcgU2V0KCksIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGtpbmQgPT0gXCJUcnlTdGF0ZW1lbnRcIikge1xuICAgIGNvbnN0IGhhbmRsZXIgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlRyeVN0YXRlbWVudH0gKi8gKHN0YXRlbWVudClcbiAgICBjb25zdCB0cnlMb2NhdGlvbiA9IHJlcXVpcmVTZW1hbnRpY0xvY2F0aW9uKG93bkxvY2F0aW9uLCBsYW5ndWFnZSwgXCJUcnlTdGF0ZW1lbnQgbG9jYXRpb25cIiwgb3duZXJMb2NhdGlvbilcbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhoYW5kbGVyKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIilcblxuICAgIGlmIChmaWVsZHMgIT0gXCJib2R5LGNhdGNoQmluZGluZyxjYXRjaEJvZHksY2F0Y2hUeXBlLGtpbmQsbG9jYXRpb25cIikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBUcnlTdGF0ZW1lbnRcIiwgdHJ5TG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlRXJyb3JUeXBlU2hhcGUoaGFuZGxlci5jYXRjaFR5cGUsIGxhbmd1YWdlLCB0cnlMb2NhdGlvbilcbiAgICBjb25zdCBiaW5kaW5nID0gaGFuZGxlci5jYXRjaEJpbmRpbmdcbiAgICBjb25zdCBiaW5kaW5nRmllbGRzID0gYmluZGluZyAmJiB0eXBlb2YgYmluZGluZyA9PSBcIm9iamVjdFwiICYmICFBcnJheS5pc0FycmF5KGJpbmRpbmcpXG4gICAgICA/IE9iamVjdC5rZXlzKGJpbmRpbmcpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKSA6IFwiXCJcbiAgICBjb25zdCBiaW5kaW5nTG9jYXRpb24gPSByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihiaW5kaW5nPy5sb2NhdGlvbiwgbGFuZ3VhZ2UsIFwiY2F0Y2ggYmluZGluZyBsb2NhdGlvblwiLCB0cnlMb2NhdGlvbilcblxuICAgIGlmICghYmluZGluZyB8fCBiaW5kaW5nLmtpbmQgIT0gXCJDYXRjaEJpbmRpbmdcIiB8fCBiaW5kaW5nRmllbGRzICE9IFwia2luZCxsb2NhdGlvbixtdXRhYmxlLG5hbWUsdHlwZVwiIHx8IGJpbmRpbmcubXV0YWJsZSAhPT0gZmFsc2UpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgY2F0Y2ggYmluZGluZ1wiLCBiaW5kaW5nTG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlVGFyZ2V0QmluZGluZ0lkZW50aWZpZXIobGFuZ3VhZ2UsIGJpbmRpbmcubmFtZSwgXCJjYXRjaCBiaW5kaW5nXCIsIGJpbmRpbmdMb2NhdGlvbilcbiAgICB2YWxpZGF0ZUVycm9yVHlwZVNoYXBlKGJpbmRpbmcudHlwZSwgbGFuZ3VhZ2UsIGJpbmRpbmdMb2NhdGlvbilcbiAgICBpZiAoYmluZGluZy50eXBlLmRlY2xhcmF0aW9uSWQgIT0gaGFuZGxlci5jYXRjaFR5cGUuZGVjbGFyYXRpb25JZCkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImNhdGNoIGJpbmRpbmcgdHlwZSBtaXNtYXRjaFwiLCBiaW5kaW5nTG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlQmxvY2soaGFuZGxlci5ib2R5LCBsYW5ndWFnZSwgdHJ5TG9jYXRpb24sIGxvb3BDb250ZXh0LCBhY3RpdmVQYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIHZhbGlkYXRlQmxvY2soaGFuZGxlci5jYXRjaEJvZHksIGxhbmd1YWdlLCB0cnlMb2NhdGlvbiwgbG9vcENvbnRleHQsIGFjdGl2ZVBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cblxuICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBzdGF0ZW1lbnQgJHtraW5kfWAsIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgY2xvc2VkIHBhcnNlci1uZXV0cmFsIGVycm9yIHR5cGUgc2hhcGUuXG4gKiBAcGFyYW0ge3Vua25vd259IHR5cGUgLSBDYW5kaWRhdGUgZXJyb3IgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IG93bmVyTG9jYXRpb24gLSBOZWFyZXN0IG93bmluZyBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUVycm9yVHlwZVNoYXBlKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gdHlwZSxcbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9ICovIGxhbmd1YWdlLFxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSAqLyBvd25lckxvY2F0aW9uKSB7XG4gIGNvbnN0IGZpZWxkcyA9IHR5cGUgJiYgdHlwZW9mIHR5cGUgPT0gXCJvYmplY3RcIiAmJiAhQXJyYXkuaXNBcnJheSh0eXBlKVxuICAgID8gT2JqZWN0LmtleXModHlwZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpIDogXCJcIlxuICBjb25zdCBjYW5kaWRhdGUgPSB0eXBlICYmIHR5cGVvZiB0eXBlID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkodHlwZSlcbiAgICA/IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovICh0eXBlKSA6IHt9XG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IFwiRXJyb3JUeXBlXCIgfHwgZmllbGRzICE9IFwiZGVjbGFyYXRpb25JZCxraW5kXCIgfHwgdHlwZW9mIGNhbmRpZGF0ZS5kZWNsYXJhdGlvbklkICE9IFwic3RyaW5nXCIgfHxcbiAgICAhL14oPzooPzpbYS16XVthLXowLTkuXy1dKiMpP2Vycm9yOlswLTldK3woPzptb2R1bGU6WzAtOV0rXFwvKT9jYXBhYmlsaXR5OlswLTldK1xcL2ZhaWx1cmU6WzAtOV0rKSQvdVxuICAgICAgLnRlc3QoY2FuZGlkYXRlLmRlY2xhcmF0aW9uSWQpKSB7XG4gICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBlcnJvciB0eXBlXCIsIG93bmVyTG9jYXRpb24pXG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgY29tcGxldGUgc2VtYW50aWMgbG9jYXRpb24gc3VpdGFibGUgZm9yIGRpYWdub3N0aWMgY29uc3RydWN0aW9uLlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBQcmVmZXJyZWQgbG9jYXRpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IGZhbGxiYWNrIC0gTmVhcmVzdCBlbmNsb3NpbmcgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24gfCB1bmRlZmluZWR9IFNhZmUgZGlhZ25vc3RpYyBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gZGlhZ25vc3RpY0xvY2F0aW9uKGNhbmRpZGF0ZSwgZmFsbGJhY2spIHtcbiAgaWYgKGlzU2VtYW50aWNMb2NhdGlvbihjYW5kaWRhdGUpKSByZXR1cm4gY2FuZGlkYXRlXG4gIGlmIChpc1NlbWFudGljTG9jYXRpb24oZmFsbGJhY2spKSByZXR1cm4gZmFsbGJhY2tcblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUmVxdWlyZXMgb25lIGNvbXBsZXRlIHBhcnNlci1uZXV0cmFsIGxvY2F0aW9uIGJlZm9yZSBhbnkgYmFja2VuZCBvciBkaWFnbm9zdGljIGNvbnN1bWVzIGl0LlxuICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBSZXF1aXJlZCBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIEJhY2tlbmQgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ViamVjdCAtIExvY2F0aW9uIG93bmVyIGZvciBhIGRldGVybWluaXN0aWMgZGlhZ25vc3RpYy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZmFsbGJhY2sgLSBOZWFyZXN0IGVuY2xvc2luZyBsb2NhdGlvbi5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gVmFsaWRhdGVkIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiByZXF1aXJlU2VtYW50aWNMb2NhdGlvbihjYW5kaWRhdGUsIGxhbmd1YWdlLCBzdWJqZWN0LCBmYWxsYmFjaykge1xuICBpZiAoIWlzU2VtYW50aWNMb2NhdGlvbihjYW5kaWRhdGUpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBtaXNzaW5nIG9yIGludmFsaWQgJHtzdWJqZWN0fWAsIGRpYWdub3N0aWNMb2NhdGlvbihmYWxsYmFjaywgdW5kZWZpbmVkKSlcblxuICByZXR1cm4gY2FuZGlkYXRlXG59XG5cbi8qKlxuICogQ2hlY2tzIGEgY29tcGxldGUgb3JkZXJlZCBVVEYtMTYgc291cmNlIHJhbmdlLlxuICogQHBhcmFtIHt1bmtub3dufSBsb2NhdGlvbiAtIENhbmRpZGF0ZSBzb3VyY2UgcmFuZ2UuXG4gKiBAcmV0dXJucyB7bG9jYXRpb24gaXMgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFdoZXRoZXIgdGhlIHJhbmdlIGlzIHNhZmUgdG8gY29uc3VtZS5cbiAqL1xuZnVuY3Rpb24gaXNTZW1hbnRpY0xvY2F0aW9uKGxvY2F0aW9uKSB7XG4gIGlmICghbG9jYXRpb24gfHwgdHlwZW9mIGxvY2F0aW9uICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShsb2NhdGlvbikpIHJldHVybiBmYWxzZVxuICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge3tmaWxlbmFtZT86IHVua25vd24sIHN0YXJ0PzogdW5rbm93biwgZW5kPzogdW5rbm93bn19ICovIChsb2NhdGlvbilcblxuICBpZiAodHlwZW9mIGNhbmRpZGF0ZS5maWxlbmFtZSAhPSBcInN0cmluZ1wiIHx8IGNhbmRpZGF0ZS5maWxlbmFtZS5sZW5ndGggPT0gMCB8fFxuICAgICFpc1NlbWFudGljUG9pbnQoY2FuZGlkYXRlLnN0YXJ0KSB8fCAhaXNTZW1hbnRpY1BvaW50KGNhbmRpZGF0ZS5lbmQpKSByZXR1cm4gZmFsc2VcblxuICByZXR1cm4gY2FuZGlkYXRlLmVuZC5vZmZzZXQgPj0gY2FuZGlkYXRlLnN0YXJ0Lm9mZnNldCAmJiBjYW5kaWRhdGUuZW5kLmxpbmUgPj0gY2FuZGlkYXRlLnN0YXJ0LmxpbmUgJiZcbiAgICAoY2FuZGlkYXRlLmVuZC5saW5lICE9IGNhbmRpZGF0ZS5zdGFydC5saW5lIHx8IGNhbmRpZGF0ZS5lbmQuY29sdW1uID49IGNhbmRpZGF0ZS5zdGFydC5jb2x1bW4pXG59XG5cbi8qKlxuICogQ2hlY2tzIG9uZSBjb21wbGV0ZSBvbmUtYmFzZWQgVVRGLTE2IHNvdXJjZSBwb2ludC5cbiAqIEBwYXJhbSB7dW5rbm93bn0gcG9pbnQgLSBDYW5kaWRhdGUgc291cmNlIHBvaW50LlxuICogQHJldHVybnMge3BvaW50IGlzIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZVBvaW50fSBXaGV0aGVyIGFsbCBjb29yZGluYXRlcyBhcmUgdmFsaWQuXG4gKi9cbmZ1bmN0aW9uIGlzU2VtYW50aWNQb2ludChwb2ludCkge1xuICBpZiAoIXBvaW50IHx8IHR5cGVvZiBwb2ludCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocG9pbnQpKSByZXR1cm4gZmFsc2VcbiAgY29uc3QgY2FuZGlkYXRlID0gLyoqIEB0eXBlIHt7b2Zmc2V0PzogdW5rbm93biwgbGluZT86IHVua25vd24sIGNvbHVtbj86IHVua25vd259fSAqLyAocG9pbnQpXG5cbiAgcmV0dXJuIE51bWJlci5pc1NhZmVJbnRlZ2VyKGNhbmRpZGF0ZS5vZmZzZXQpICYmIE51bWJlcihjYW5kaWRhdGUub2Zmc2V0KSA+PSAwICYmXG4gICAgTnVtYmVyLmlzU2FmZUludGVnZXIoY2FuZGlkYXRlLmxpbmUpICYmIE51bWJlcihjYW5kaWRhdGUubGluZSkgPj0gMSAmJlxuICAgIE51bWJlci5pc1NhZmVJbnRlZ2VyKGNhbmRpZGF0ZS5jb2x1bW4pICYmIE51bWJlcihjYW5kaWRhdGUuY29sdW1uKSA+PSAxXG59XG5cbi8qKlxuICogVmFsaWRhdGVzIHRoZSBzaW1wbGUgaWRlbnRpZmllciB0YXJnZXQgaW50cm9kdWNlZCBieSB0YXNrIDAwMi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdGFyZ2V0IC0gQ2FuZGlkYXRlIGFzc2lnbm1lbnQgdGFyZ2V0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gQmFja2VuZCBsYW5ndWFnZSBvciBiaW5hcnkgdGFyZ2V0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiB8IHVuZGVmaW5lZH0gb3duZXJMb2NhdGlvbiAtIEFzc2lnbm1lbnQgbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVBc3NpZ25tZW50VGFyZ2V0KHRhcmdldCwgbGFuZ3VhZ2UsIG93bmVyTG9jYXRpb24pIHtcbiAgaWYgKCF0YXJnZXQgfHwgdHlwZW9mIHRhcmdldCAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkodGFyZ2V0KSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBpbnZhbGlkIGFzc2lnbm1lbnQgdGFyZ2V0XCIsIG93bmVyTG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLklkZW50aWZpZXJFeHByZXNzaW9ufSAqLyAodGFyZ2V0KVxuICBjb25zdCBsb2NhdGlvbiA9IGNhbmRpZGF0ZS5sb2NhdGlvbiA/PyBvd25lckxvY2F0aW9uXG5cbiAgaWYgKGNhbmRpZGF0ZS5raW5kICE9IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBhc3NpZ25tZW50IHRhcmdldCAke1N0cmluZyhSZWZsZWN0LmdldCh0YXJnZXQsIFwia2luZFwiKSl9YCwgbG9jYXRpb24pXG4gIH1cblxuICB2YWxpZGF0ZVRhcmdldEJpbmRpbmdJZGVudGlmaWVyKGxhbmd1YWdlLCBjYW5kaWRhdGUubmFtZSwgXCJhc3NpZ25tZW50IHRhcmdldFwiLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBDaGVja3MgZXhwcmVzc2lvbiBiYWNrZW5kIGNhcGFiaWxpdGllcyByZWN1cnNpdmVseS5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZXhwcmVzc2lvbiAtIENhbmRpZGF0ZSBzZW1hbnRpYyBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gQmFja2VuZCBsYW5ndWFnZSBvciBiaW5hcnkgdGFyZ2V0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiB8IHVuZGVmaW5lZH0gb3duZXJMb2NhdGlvbiAtIE5lYXJlc3Qgb3duaW5nIG5vZGUgbG9jYXRpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd0phdmFOZWdhdGVkTWluaW11bU9wZXJhbmRdIC0gV2hldGhlciBKYXZhIG1heSB1c2UgMjE0NzQ4MzY0OCBvbmx5IGJlbmVhdGggaW50ZWdlciBuZWdhdGlvbi5cbiAqIEBwYXJhbSB7U2V0PG9iamVjdD59IFthY3RpdmVQYXRoXSAtIEFuY2VzdG9ycyBvbiB0aGUgY3VycmVudCByZWN1cnNpdmUgdmFsaWRhdGlvbiBwYXRoLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gW2V4dGVybmFsRGVjbGFyYXRpb25JZHNdIC0gUmVzb2x2ZWQgZGVjbGFyYXRpb25zIHdob3NlIHNvdXJjZSBzcGVsbGluZyBpcyB0YXJnZXQtaW5kZXBlbmRlbnQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFthbGxvd0phdmFPcmRlcmVkTWFwUm9vdF0gLSBXaGV0aGVyIHRoaXMgcm9vdCBpcyBhIEphdmEgbG9jYWwgaW5pdGlhbGl6ZXIgZWxpZ2libGUgZm9yIHN0YXRlbWVudCBsb3dlcmluZy5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbiwgbGFuZ3VhZ2UsIG93bmVyTG9jYXRpb24sIGFsbG93SmF2YU5lZ2F0ZWRNaW5pbXVtT3BlcmFuZCA9IGZhbHNlLCBhY3RpdmVQYXRoID0gbmV3IFNldCgpLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzID0gbmV3IFNldCgpLCBhbGxvd0phdmFPcmRlcmVkTWFwUm9vdCA9IGZhbHNlKSB7XG4gIGlmICghZXhwcmVzc2lvbiB8fCB0eXBlb2YgZXhwcmVzc2lvbiAhPSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoZXhwcmVzc2lvbikpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBleHByZXNzaW9uXCIsIG93bmVyTG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovIChleHByZXNzaW9uKVxuICBjb25zdCBsb2NhdGlvbiA9IGNhbmRpZGF0ZS5sb2NhdGlvbiA/PyBvd25lckxvY2F0aW9uXG5cbiAgaWYgKGFjdGl2ZVBhdGguaGFzKGNhbmRpZGF0ZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJjeWNsaWMgZXhwcmVzc2lvblwiLCBsb2NhdGlvbilcbiAgY29uc3QgZXhwcmVzc2lvblBhdGggPSBuZXcgU2V0KGFjdGl2ZVBhdGgpXG5cbiAgZXhwcmVzc2lvblBhdGguYWRkKGNhbmRpZGF0ZSlcblxuICBpZiAodHlwZW9mIGNhbmRpZGF0ZS5raW5kICE9IFwic3RyaW5nXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBleHByZXNzaW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHtcbiAgICB2YWxpZGF0ZVRhcmdldElkZW50aWZpZXIobGFuZ3VhZ2UsIGNhbmRpZGF0ZS5uYW1lLCBcInJlZmVyZW5jZVwiLCBsb2NhdGlvbilcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICBpZiAoZmllbGRzICE9IFwiY2xhc3NJZCxraW5kLGxvY2F0aW9uXCIgfHwgdHlwZW9mIGNhbmRpZGF0ZS5jbGFzc0lkICE9IFwic3RyaW5nXCIgfHxcbiAgICAgICEvXig/OlthLXpdW2EtejAtOS5fLV0qIyk/Y2xhc3M6WzAtOV0rJC91LnRlc3QoY2FuZGlkYXRlLmNsYXNzSWQpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIHByaXZhdGUgZmllbGQgcmVjZWl2ZXJcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkVycm9yTWVzc2FnZVJlYWRcIikge1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG5cbiAgICBpZiAoZmllbGRzICE9IFwia2luZCxsb2NhdGlvbixyZWNlaXZlclwiIHx8IGNhbmRpZGF0ZS5yZWNlaXZlcj8ua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgRXJyb3JNZXNzYWdlUmVhZFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVFeHByZXNzaW9uKGNhbmRpZGF0ZS5yZWNlaXZlciwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3duZWRNb3ZlRXhwcmVzc2lvblwiIHx8IGNhbmRpZGF0ZS5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuICAgIGNvbnN0IGV4cGVjdGVkID0gY2FuZGlkYXRlLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgPyBcImV4cHJlc3Npb24sa2luZCxsb2NhdGlvbix0eXBlXCIgOiBcImV4cHJlc3Npb24sa2luZCxsb2NhdGlvbixtb2RlLHR5cGVcIlxuXG4gICAgaWYgKGZpZWxkcyAhPSBleHBlY3RlZCB8fCBjYW5kaWRhdGUuZXhwcmVzc2lvbi5raW5kICE9IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiAmJiBjYW5kaWRhdGUuZXhwcmVzc2lvbi5raW5kICE9IFwiUmVjZWl2ZXJFeHByZXNzaW9uXCIgJiZcbiAgICAgIGNhbmRpZGF0ZS5leHByZXNzaW9uLmtpbmQgIT0gXCJQcml2YXRlRmllbGRSZWFkXCIpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYG1hbGZvcm1lZCAke2NhbmRpZGF0ZS5raW5kfWAsIGxvY2F0aW9uKVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUuZXhwcmVzc2lvbiwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiSW50ZWdlckxpdGVyYWxcIikge1xuICAgIGlmICghTnVtYmVyLmlzU2FmZUludGVnZXIoY2FuZGlkYXRlLnZhbHVlKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm5vbi1zYWZlIGludGVnZXIgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgdmFsaWROZWdhdGVkTWluaW11bU9wZXJhbmQgPSBhbGxvd0phdmFOZWdhdGVkTWluaW11bU9wZXJhbmQgJiYgY2FuZGlkYXRlLnZhbHVlID09IDIxNDc0ODM2NDhcblxuICAgIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIiAmJiAhdmFsaWROZWdhdGVkTWluaW11bU9wZXJhbmQgJiYgKGNhbmRpZGF0ZS52YWx1ZSA8IC0yMTQ3NDgzNjQ4IHx8IGNhbmRpZGF0ZS52YWx1ZSA+IDIxNDc0ODM2NDcpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiaW50ZWdlciBsaXRlcmFsIG91dHNpZGUgc2lnbmVkIDMyLWJpdCBpbnQgcmFuZ2VcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICgobGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiB8fCBsYW5ndWFnZSA9PSBcImdvXCIgfHwgbGFuZ3VhZ2UgPT0gXCJjXCIgfHwgbGFuZ3VhZ2UgPT0gXCJjcHBcIiB8fCBsYW5ndWFnZSA9PSBcImRhcnRcIiB8fCBsYW5ndWFnZSA9PSBcImtvdGxpblwiIHx8IGxhbmd1YWdlID09IFwicnVzdFwiIHx8IGxhbmd1YWdlID09IFwic3dpZnRcIikgJiYgY2FuZGlkYXRlLnZhbHVlIDwgMCB8fFxuICAgICAgKGxhbmd1YWdlID09IFwiY1wiIHx8IGxhbmd1YWdlID09IFwiY3BwXCIgfHwgbGFuZ3VhZ2UgPT0gXCJkYXJ0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJrb3RsaW5cIiB8fCBsYW5ndWFnZSA9PSBcInJ1c3RcIiB8fCBsYW5ndWFnZSA9PSBcInN3aWZ0XCIpICYmIE9iamVjdC5pcyhjYW5kaWRhdGUudmFsdWUsIC0wKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm5lZ2F0aXZlIGludGVnZXIgbGl0ZXJhbCB3aXRob3V0IHNlbWFudGljIG5lZ2F0aW9uXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiIHx8IGNhbmRpZGF0ZS5raW5kID09IFwiU3RyaW5nTGl0ZXJhbFwiKSByZXR1cm5cbiAgaWYgKFtcIk9wdGlvbmFsTm9uZVwiLCBcIk9wdGlvbmFsU29tZVwiLCBcIk9wdGlvbmFsSXNQcmVzZW50XCIsIFwiT3B0aW9uYWxVbndyYXBcIl0uaW5jbHVkZXMoY2FuZGlkYXRlLmtpbmQpKSB7XG4gICAgaWYgKCF0YXNrMDA3TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNyBvcHRpb25hbCB2YWx1ZXNcIiwgbG9jYXRpb24pXG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIilcbiAgICBjb25zdCBleHBlY3RlZEZpZWxkcyA9IGNhbmRpZGF0ZS5raW5kID09IFwiT3B0aW9uYWxOb25lXCIgPyBcImtpbmQsbG9jYXRpb25cIiA6XG4gICAgICBjYW5kaWRhdGUua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiID8gXCJraW5kLGxvY2F0aW9uLHZhbHVlXCIgOiBcImtpbmQsbG9jYXRpb24sb3BlcmFuZFwiXG5cbiAgICBpZiAoZmllbGRzICE9IGV4cGVjdGVkRmllbGRzKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBtYWxmb3JtZWQgJHtjYW5kaWRhdGUua2luZH1gLCBsb2NhdGlvbilcbiAgICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPcHRpb25hbE5vbmVcIikgcmV0dXJuXG4gICAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3B0aW9uYWxTb21lXCIpIHtcbiAgICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUudmFsdWUsIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGNvbnN0IG9wZXJhdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuT3B0aW9uYWxJc1ByZXNlbnQgfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5PcHRpb25hbFVud3JhcH0gKi8gKGNhbmRpZGF0ZSlcblxuICAgIGlmICghb3BlcmF0aW9uLm9wZXJhbmQgfHwgb3BlcmF0aW9uLm9wZXJhbmQua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgYCR7Y2FuZGlkYXRlLmtpbmR9IHdpdGhvdXQgYSBzaW1wbGUgaWRlbnRpZmllciBvcGVyYW5kYCwgbG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihvcGVyYXRpb24ub3BlcmFuZCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKFtcIkxpc3RMaXRlcmFsXCIsIFwiTWFwTGl0ZXJhbFwiLCBcIk9yZGVyZWRNYXBMaXRlcmFsXCIsIFwiTGlzdEluZGV4RXhwcmVzc2lvblwiLCBcIk1hcExvb2t1cEV4cHJlc3Npb25cIiwgXCJDb2xsZWN0aW9uU2l6ZUV4cHJlc3Npb25cIl0uaW5jbHVkZXMoY2FuZGlkYXRlLmtpbmQpKSB7XG4gICAgaWYgKCF0YXNrMDA2TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJUYXNrIDAwNiBpbW11dGFibGUgY29sbGVjdGlvbnNcIiwgbG9jYXRpb24pXG4gICAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIiAmJiAhdGFzazAxNExhbmd1YWdlcy5oYXMobGFuZ3VhZ2UpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiVGFzayAwMTQgb3JkZXJlZC1tYXAgaXRlcmF0aW9uXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJPcmRlcmVkTWFwTGl0ZXJhbFwiICYmIGxhbmd1YWdlID09IFwiamF2YVwiICYmICFhbGxvd0phdmFPcmRlcmVkTWFwUm9vdCkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcInVuc2FmZSBKYXZhIG9yZGVyZWQtbWFwIGV4cHJlc3Npb24gbG93ZXJpbmdcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkxpc3RMaXRlcmFsXCIpIHtcbiAgICAgIGlmICghaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5lbGVtZW50cykpIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIHNwYXJzZSBsaXN0IGVsZW1lbnRzXCIsIGxvY2F0aW9uKVxuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGNhbmRpZGF0ZS5lbGVtZW50cykge1xuICAgICAgICB2YWxpZGF0ZUV4cHJlc3Npb24oZWxlbWVudCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgICB9XG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiTWFwTGl0ZXJhbFwiIHx8IGNhbmRpZGF0ZS5raW5kID09IFwiT3JkZXJlZE1hcExpdGVyYWxcIikge1xuICAgICAgaWYgKCFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlLmVudHJpZXMpKSB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWlzc2luZyBvciBzcGFyc2UgbWFwIGVudHJpZXNcIiwgbG9jYXRpb24pXG4gICAgICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJNYXBMaXRlcmFsXCIgJiYgbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgJiYgY2FuZGlkYXRlLmVudHJpZXMubGVuZ3RoID4gMTApIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImphdmEudXRpbC5NYXAub2Ygc3VwcG9ydHMgYXQgbW9zdCB0ZW4gZW50cmllc1wiLCBsb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3QgZW50cnkgb2YgY2FuZGlkYXRlLmVudHJpZXMpIHtcbiAgICAgICAgaWYgKCFlbnRyeSB8fCBlbnRyeS5raW5kICE9IFwiTWFwRW50cnlcIiB8fCAhZW50cnkua2V5IHx8IGVudHJ5LmtleS5raW5kICE9IFwiU3RyaW5nTGl0ZXJhbFwiKSB7XG4gICAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBtYXAgZW50cnlcIiwgZW50cnk/LmxvY2F0aW9uID8/IGxvY2F0aW9uKVxuICAgICAgICB9XG4gICAgICAgIHZhbGlkYXRlRXhwcmVzc2lvbihlbnRyeS5rZXksIGxhbmd1YWdlLCBlbnRyeS5sb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgICAgICB2YWxpZGF0ZUV4cHJlc3Npb24oZW50cnkudmFsdWUsIGxhbmd1YWdlLCBlbnRyeS5sb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgICAgfVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkxpc3RJbmRleEV4cHJlc3Npb25cIikge1xuICAgICAgaWYgKGNhbmRpZGF0ZS50b3RhbGl0eSA9PSBcImZhaWwtb24tYWJzZW5jZVwiICYmIGxhbmd1YWdlICE9IFwiamF2YVwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJsaXN0IGFjY2VzcyBkZXBlbmRzIG9uIEphdmEtc3BlY2lmaWMgYm91bmRzIGZhaWx1cmVcIiwgbG9jYXRpb24pXG4gICAgICB9XG4gICAgICB2YWxpZGF0ZUV4cHJlc3Npb24oY2FuZGlkYXRlLmNvbGxlY3Rpb24sIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgICAgdmFsaWRhdGVFeHByZXNzaW9uKGNhbmRpZGF0ZS5pbmRleCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiTWFwTG9va3VwRXhwcmVzc2lvblwiKSB7XG4gICAgICBpZiAoY2FuZGlkYXRlLnRvdGFsaXR5ID09IFwiZmFpbC1vbi1hYnNlbmNlXCIgJiYgbGFuZ3VhZ2UgIT0gXCJydWJ5XCIpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hcCBsb29rdXAgZGVwZW5kcyBvbiBSdWJ5IGZldGNoIGFic2VuY2UgZmFpbHVyZVwiLCBsb2NhdGlvbilcbiAgICAgIH1cbiAgICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUuY29sbGVjdGlvbiwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgICB2YWxpZGF0ZUV4cHJlc3Npb24oY2FuZGlkYXRlLmtleSwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHtcbiAgICAgIGlmIChjYW5kaWRhdGUuY29sbGVjdGlvbktpbmQgIT0gXCJsaXN0XCIgJiYgY2FuZGlkYXRlLmNvbGxlY3Rpb25LaW5kICE9IFwibWFwXCIpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImNvbGxlY3Rpb24gc2l6ZSB3aXRob3V0IGEgdmFsaWRhdGVkIHJlY2VpdmVyIGtpbmRcIiwgbG9jYXRpb24pXG4gICAgICB9XG4gICAgICB2YWxpZGF0ZUV4cHJlc3Npb24oY2FuZGlkYXRlLmNvbGxlY3Rpb24sIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbklkID0gY2FuZGlkYXRlLnJlc29sdXRpb24gJiYgdHlwZW9mIGNhbmRpZGF0ZS5yZXNvbHV0aW9uID09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoY2FuZGlkYXRlLnJlc29sdXRpb24pXG4gICAgICA/IFJlZmxlY3QuZ2V0KGNhbmRpZGF0ZS5yZXNvbHV0aW9uLCBcImRlY2xhcmF0aW9uSWRcIilcbiAgICAgIDogdW5kZWZpbmVkXG5cbiAgICBpZiAodHlwZW9mIGRlY2xhcmF0aW9uSWQgIT0gXCJzdHJpbmdcIiB8fCAhZXh0ZXJuYWxEZWNsYXJhdGlvbklkcy5oYXMoZGVjbGFyYXRpb25JZCkpIHtcbiAgICAgIHZhbGlkYXRlVGFyZ2V0SWRlbnRpZmllcihsYW5ndWFnZSwgY2FuZGlkYXRlLmNhbGxlZSwgXCJjYWxsZWVcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghY2FuZGlkYXRlLnJlc29sdXRpb24gfHwgdHlwZW9mIGNhbmRpZGF0ZS5yZXNvbHV0aW9uICE9IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShjYW5kaWRhdGUucmVzb2x1dGlvbikpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtaXNzaW5nIG9yIGludmFsaWQgcmVzb2x2ZWQgY2FsbCBzaWduYXR1cmVcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghQXJyYXkuaXNBcnJheShjYW5kaWRhdGUuYXJndW1lbnRzKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBjYWxsIGFyZ3VtZW50c1wiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKCF0YXNrMDA1TGFuZ3VhZ2VzLmhhcyhsYW5ndWFnZSkgJiYgY2FuZGlkYXRlLmFyZ3VtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcImNhbGwgYXJndW1lbnQgY291bnQgb3RoZXIgdGhhbiB0d29cIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGZvciAoY29uc3QgYXJndW1lbnQgb2YgY2FuZGlkYXRlLmFyZ3VtZW50cykge1xuICAgICAgdmFsaWRhdGVFeHByZXNzaW9uKGFyZ3VtZW50LCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBleHByZXNzaW9uUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiRWZmZWN0Q2FsbEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG4gICAgY29uc3QgcmVzb2x1dGlvbiA9IGNhbmRpZGF0ZS5yZXNvbHV0aW9uXG5cbiAgICBpZiAoZmllbGRzICE9IFwiYXJndW1lbnRzLGVmZmVjdFNpdGVJZCxraW5kLGxvY2F0aW9uLG9wZXJhdGlvbixyZXNvbHV0aW9uXCIgfHwgIWlzRGVuc2VBcnJheShjYW5kaWRhdGUuYXJndW1lbnRzKSB8fFxuICAgICAgdHlwZW9mIGNhbmRpZGF0ZS5lZmZlY3RTaXRlSWQgIT0gXCJzdHJpbmdcIiB8fCB0eXBlb2YgY2FuZGlkYXRlLm9wZXJhdGlvbiAhPSBcInN0cmluZ1wiIHx8ICFyZXNvbHV0aW9uIHx8XG4gICAgICByZXNvbHV0aW9uLmtpbmQgIT0gXCJSZXNvbHZlZEVmZmVjdE9wZXJhdGlvblNpZ25hdHVyZVwiIHx8IHJlc29sdXRpb24ub3BlcmF0aW9uSWQgIT0gY2FuZGlkYXRlLm9wZXJhdGlvbiB8fFxuICAgICAgIWlzRGVuc2VBcnJheShyZXNvbHV0aW9uLnBhcmFtZXRlclR5cGVzKSB8fCAhaXNEZW5zZUFycmF5KHJlc29sdXRpb24uZmFpbHVyZUlkcykgfHwgcmVzb2x1dGlvbi5lZmZlY3RzPy5qb2luKFwiLFwiKSAhPSBcImhvc3RcIikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBhdXRob3JpemVkIGVmZmVjdCBjYWxsXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIGNhbmRpZGF0ZS5hcmd1bWVudHMpIHZhbGlkYXRlRXhwcmVzc2lvbihhcmd1bWVudCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiUmVmZXJlbmNlQ29uc3RydWN0aW9uXCIpIHtcbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuICAgIGNvbnN0IHJlc29sdXRpb24gPSBjYW5kaWRhdGUucmVzb2x1dGlvblxuICAgIGNvbnN0IGVmZmVjdGZ1bEZpZWxkcyA9IFwiYXJndW1lbnRzLGVmZmVjdFNpdGVJZCxlZmZlY3RzLGZhaWx1cmVJZHMsa2luZCxsb2NhdGlvbixyZWZlcmVuY2UscmVzb2x1dGlvblwiXG4gICAgY29uc3QgcHVyZUZpZWxkcyA9IFwiYXJndW1lbnRzLGtpbmQsbG9jYXRpb24scmVmZXJlbmNlLHJlc29sdXRpb25cIlxuXG4gICAgaWYgKCFbcHVyZUZpZWxkcywgZWZmZWN0ZnVsRmllbGRzXS5pbmNsdWRlcyhmaWVsZHMpIHx8XG4gICAgICBjYW5kaWRhdGUucmVmZXJlbmNlPy5raW5kICE9IFwiUmVmZXJlbmNlVHlwZVwiICYmIGNhbmRpZGF0ZS5yZWZlcmVuY2U/LmtpbmQgIT0gXCJPd25lZFJlZmVyZW5jZVR5cGVcIiB8fFxuICAgICAgdHlwZW9mIGNhbmRpZGF0ZS5yZWZlcmVuY2UuZGVjbGFyYXRpb25JZCAhPSBcInN0cmluZ1wiIHx8ICFpc0RlbnNlQXJyYXkoY2FuZGlkYXRlLmFyZ3VtZW50cykgfHxcbiAgICAgICFyZXNvbHV0aW9uIHx8IHJlc29sdXRpb24ua2luZCAhPSBcIlJlc29sdmVkQ29uc3RydWN0b3JTaWduYXR1cmVcIiB8fFxuICAgICAgcmVzb2x1dGlvbi5kZWNsYXJhdGlvbklkICE9IGAke2NhbmRpZGF0ZS5yZWZlcmVuY2UuZGVjbGFyYXRpb25JZH06Y29uc3RydWN0b3JgIHx8ICFpc0RlbnNlQXJyYXkocmVzb2x1dGlvbi5wYXJhbWV0ZXJUeXBlcykgfHxcbiAgICAgIGZpZWxkcyA9PSBlZmZlY3RmdWxGaWVsZHMgJiZcbiAgICAgICh0eXBlb2YgY2FuZGlkYXRlLmVmZmVjdFNpdGVJZCAhPSBcInN0cmluZ1wiIHx8IGNhbmRpZGF0ZS5lZmZlY3RzPy5qb2luKFwiLFwiKSAhPSBcImhvc3RcIiB8fCAhaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5mYWlsdXJlSWRzKSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgcmVmZXJlbmNlIGNvbnN0cnVjdGlvbiBvciByZXNvbHZlZCBjb25zdHJ1Y3RvciBzaWduYXR1cmVcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGZvciAoY29uc3QgYXJndW1lbnQgb2YgY2FuZGlkYXRlLmFyZ3VtZW50cykge1xuICAgICAgdmFsaWRhdGVFeHByZXNzaW9uKGFyZ3VtZW50LCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBleHByZXNzaW9uUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGZpZWxkcyA9IE9iamVjdC5rZXlzKGNhbmRpZGF0ZSkuZmlsdGVyKChrZXkpID0+IGtleSAhPSBcInNvdXJjZVByb3ZlbmFuY2VcIikuc29ydCgpLmpvaW4oXCIsXCIpXG4gICAgY29uc3QgcmVzb2x1dGlvbiA9IGNhbmRpZGF0ZS5yZXNvbHV0aW9uXG5cbiAgICBjb25zdCBlZmZlY3RmdWxGaWVsZHMgPSBcImFyZ3VtZW50cyxlZmZlY3RTaXRlSWQsZWZmZWN0cyxmYWlsdXJlSWRzLGtpbmQsbG9jYXRpb24sbWV0aG9kLHJlY2VpdmVyLHJlc29sdXRpb25cIlxuICAgIGNvbnN0IHB1cmVGaWVsZHMgPSBcImFyZ3VtZW50cyxraW5kLGxvY2F0aW9uLG1ldGhvZCxyZWNlaXZlcixyZXNvbHV0aW9uXCJcblxuICAgIGlmICghW3B1cmVGaWVsZHMsIGVmZmVjdGZ1bEZpZWxkc10uaW5jbHVkZXMoZmllbGRzKSB8fCB0eXBlb2YgY2FuZGlkYXRlLm1ldGhvZCAhPSBcInN0cmluZ1wiIHx8XG4gICAgICAhaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5hcmd1bWVudHMpIHx8ICFyZXNvbHV0aW9uIHx8IHJlc29sdXRpb24ua2luZCAhPSBcIlJlc29sdmVkTWV0aG9kU2lnbmF0dXJlXCIgfHxcbiAgICAgIHJlc29sdXRpb24uZGVjbGFyYXRpb25JZCAhPSBjYW5kaWRhdGUubWV0aG9kIHx8ICFpc0RlbnNlQXJyYXkocmVzb2x1dGlvbi5wYXJhbWV0ZXJUeXBlcykgfHxcbiAgICAgICFPYmplY3QuaGFzT3duKHJlc29sdXRpb24sIFwicmV0dXJuVHlwZVwiKSB8fCBPYmplY3QuaGFzT3duKHJlc29sdXRpb24sIFwicmVzb3VyY2VGbG93XCIpICYmXG4gICAgICAoIXJlc29sdXRpb24ucmVzb3VyY2VGbG93IHx8ICFbXCJwcmVzZXJ2ZVwiLCBcInRlcm1pbmFsXCJdLmluY2x1ZGVzKFN0cmluZyhyZXNvbHV0aW9uLnJlc291cmNlRmxvdy5raW5kKSkgfHxcbiAgICAgICAgT2JqZWN0Lmhhc093bihyZXNvbHV0aW9uLnJlc291cmNlRmxvdywgXCJ0ZXJtaW5hbEZhaWx1cmVJZFwiKSAmJiB0eXBlb2YgcmVzb2x1dGlvbi5yZXNvdXJjZUZsb3cudGVybWluYWxGYWlsdXJlSWQgIT0gXCJzdHJpbmdcIikgfHxcbiAgICAgIGZpZWxkcyA9PSBlZmZlY3RmdWxGaWVsZHMgJiZcbiAgICAgICh0eXBlb2YgY2FuZGlkYXRlLmVmZmVjdFNpdGVJZCAhPSBcInN0cmluZ1wiIHx8IGNhbmRpZGF0ZS5lZmZlY3RzPy5qb2luKFwiLFwiKSAhPSBcImhvc3RcIiB8fCAhaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5mYWlsdXJlSWRzKSkpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgcmVjZWl2ZXIgY2FsbCBvciByZXNvbHZlZCBtZXRob2Qgc2lnbmF0dXJlXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oY2FuZGlkYXRlLnJlY2VpdmVyLCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBleHByZXNzaW9uUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICBmb3IgKGNvbnN0IGFyZ3VtZW50IG9mIGNhbmRpZGF0ZS5hcmd1bWVudHMpIHtcbiAgICAgIHZhbGlkYXRlRXhwcmVzc2lvbihhcmd1bWVudCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIlJlY29yZENvbnN0cnVjdGlvblwiKSB7XG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIilcblxuICAgIGlmIChmaWVsZHMgIT0gXCJhcmd1bWVudHMsa2luZCxsb2NhdGlvbixyZWNvcmRcIiB8fCAhY2FuZGlkYXRlLnJlY29yZCB8fCBjYW5kaWRhdGUucmVjb3JkLmtpbmQgIT0gXCJSZWNvcmRUeXBlXCIgfHxcbiAgICAgIHR5cGVvZiBjYW5kaWRhdGUucmVjb3JkLmRlY2xhcmF0aW9uSWQgIT0gXCJzdHJpbmdcIiB8fCAhaXNEZW5zZUFycmF5KGNhbmRpZGF0ZS5hcmd1bWVudHMpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwibWFsZm9ybWVkIFJlY29yZENvbnN0cnVjdGlvblwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgZm9yIChjb25zdCBhcmd1bWVudCBvZiBjYW5kaWRhdGUuYXJndW1lbnRzKSB7XG4gICAgICB2YWxpZGF0ZUV4cHJlc3Npb24oYXJndW1lbnQsIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAoY2FuZGlkYXRlLmtpbmQgPT0gXCJNZW1iZXJSZWFkXCIpIHtcbiAgICBjb25zdCBmaWVsZHMgPSBPYmplY3Qua2V5cyhjYW5kaWRhdGUpLmZpbHRlcigoa2V5KSA9PiBrZXkgIT0gXCJzb3VyY2VQcm92ZW5hbmNlXCIpLnNvcnQoKS5qb2luKFwiLFwiKVxuXG4gICAgaWYgKGZpZWxkcyAhPSBcImZpZWxkLGtpbmQsbG9jYXRpb24scmVjZWl2ZXJcIiB8fCB0eXBlb2YgY2FuZGlkYXRlLmZpZWxkICE9IFwic3RyaW5nXCIpIHtcbiAgICAgIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgXCJtYWxmb3JtZWQgTWVtYmVyUmVhZFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVFeHByZXNzaW9uKGNhbmRpZGF0ZS5yZWNlaXZlciwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBmYWxzZSwgZXhwcmVzc2lvblBhdGgsIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiUHJpdmF0ZUZpZWxkUmVhZFwiKSB7XG4gICAgY29uc3QgZmllbGRzID0gT2JqZWN0LmtleXMoY2FuZGlkYXRlKS5maWx0ZXIoKGtleSkgPT4ga2V5ICE9IFwic291cmNlUHJvdmVuYW5jZVwiKS5zb3J0KCkuam9pbihcIixcIilcblxuICAgIGlmIChmaWVsZHMgIT0gXCJmaWVsZCxraW5kLGxvY2F0aW9uLHJlY2VpdmVyXCIgfHwgdHlwZW9mIGNhbmRpZGF0ZS5maWVsZCAhPSBcInN0cmluZ1wiIHx8XG4gICAgICBjYW5kaWRhdGUucmVjZWl2ZXI/LmtpbmQgIT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIikge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBcIm1hbGZvcm1lZCBwcml2YXRlIGZpZWxkIHJlY2VpdmVyIG9yIHByaXZhdGUgZmllbGQgaWRlbnRpdHlcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUucmVjZWl2ZXIsIGxhbmd1YWdlLCBsb2NhdGlvbiwgZmFsc2UsIGV4cHJlc3Npb25QYXRoLCBleHRlcm5hbERlY2xhcmF0aW9uSWRzKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChjYW5kaWRhdGUua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKCFPYmplY3QuaGFzT3duKHVuYXJ5T3BlcmF0aW9uU3ludGF4LCBTdHJpbmcoY2FuZGlkYXRlLm9wZXJhdGlvbikpKSB7XG4gICAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGB1bmFyeSBvcGVyYXRpb24gJHtTdHJpbmcoY2FuZGlkYXRlLm9wZXJhdGlvbil9YCwgbG9jYXRpb24pXG4gICAgfVxuICAgIHZhbGlkYXRlRXhwcmVzc2lvbihjYW5kaWRhdGUub3BlcmFuZCwgbGFuZ3VhZ2UsIGxvY2F0aW9uLCBjYW5kaWRhdGUub3BlcmF0aW9uID09IFwiSW50ZWdlck5lZ2F0ZVwiLCBleHByZXNzaW9uUGF0aCxcbiAgICAgIGV4dGVybmFsRGVjbGFyYXRpb25JZHMpXG4gICAgdmFsaWRhdGVLbm93blRhcmdldEludGVnZXIoY2FuZGlkYXRlLCBsYW5ndWFnZSwgbG9jYXRpb24pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGNhbmRpZGF0ZS5raW5kID09IFwiQmluYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKCFPYmplY3QuaGFzT3duKGJpbmFyeU9wZXJhdGlvblN5bnRheCwgU3RyaW5nKGNhbmRpZGF0ZS5vcGVyYXRpb24pKSkge1xuICAgICAgdW5zdXBwb3J0ZWRDYXBhYmlsaXR5KGxhbmd1YWdlLCBgYmluYXJ5IG9wZXJhdGlvbiAke1N0cmluZyhjYW5kaWRhdGUub3BlcmF0aW9uKX1gLCBsb2NhdGlvbilcbiAgICB9XG4gICAgdmFsaWRhdGVFeHByZXNzaW9uKGNhbmRpZGF0ZS5sZWZ0LCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBleHByZXNzaW9uUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB2YWxpZGF0ZUV4cHJlc3Npb24oY2FuZGlkYXRlLnJpZ2h0LCBsYW5ndWFnZSwgbG9jYXRpb24sIGZhbHNlLCBleHByZXNzaW9uUGF0aCwgZXh0ZXJuYWxEZWNsYXJhdGlvbklkcylcbiAgICB2YWxpZGF0ZUtub3duVGFyZ2V0SW50ZWdlcihjYW5kaWRhdGUsIGxhbmd1YWdlLCBsb2NhdGlvbilcbiAgICByZXR1cm5cbiAgfVxuXG4gIHVuc3VwcG9ydGVkQ2FwYWJpbGl0eShsYW5ndWFnZSwgU3RyaW5nKFJlZmxlY3QuZ2V0KGV4cHJlc3Npb24sIFwia2luZFwiKSksIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIFJlamVjdHMgY29tcGlsZS10aW1lLWtub3duIEphdmEgaW50ZWdlciBvcGVyYXRpb24gcmVzdWx0cyBvdXRzaWRlIHByaW1pdGl2ZSBpbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlVuYXJ5RXhwcmVzc2lvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJpbmFyeUV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBWYWxpZGF0ZWQgb3BlcmF0aW9uIHNoYXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CYWNrZW5kTGFuZ3VhZ2V9IGxhbmd1YWdlIC0gQmFja2VuZCBsYW5ndWFnZSBvciBiaW5hcnkgdGFyZ2V0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiB8IHVuZGVmaW5lZH0gbG9jYXRpb24gLSBPcGVyYXRpb24gbG9jYXRpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVLbm93blRhcmdldEludGVnZXIoZXhwcmVzc2lvbiwgbGFuZ3VhZ2UsIGxvY2F0aW9uKSB7XG4gIGNvbnN0IHZhbHVlID0ga25vd25JbnRlZ2VyVmFsdWUoZXhwcmVzc2lvbilcblxuICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJiAodmFsdWUgPCAtMjE0NzQ4MzY0OG4gfHwgdmFsdWUgPiAyMTQ3NDgzNjQ3bikpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiY29tcGlsZS10aW1lLWtub3duIGludGVnZXIgb3BlcmF0aW9uIG91dHNpZGUgc2lnbmVkIDMyLWJpdCBpbnQgcmFuZ2VcIiwgbG9jYXRpb24pXG4gIH1cbiAgaWYgKChsYW5ndWFnZSA9PSBcImNzaGFycFwiIHx8IGxhbmd1YWdlID09IFwiZ29cIiB8fCBsYW5ndWFnZSA9PSBcImNcIiB8fCBsYW5ndWFnZSA9PSBcImNwcFwiIHx8IGxhbmd1YWdlID09IFwicnVzdFwiIHx8IGxhbmd1YWdlID09IFwic3dpZnRcIiB8fCBsYW5ndWFnZSA9PSBcIndhc21cIikgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICh2YWx1ZSA8IC05MjIzMzcyMDM2ODU0Nzc1ODA4biB8fCB2YWx1ZSA+IDkyMjMzNzIwMzY4NTQ3NzU4MDduKSkge1xuICAgIGNvbnN0IHNjYWxhciA9IGxhbmd1YWdlID09IFwid2FzbVwiID8gXCJpNjRcIiA6IGxhbmd1YWdlID09IFwic3dpZnRcIiA/IFwiSW50NjRcIiA6IFwibG9uZ1wiXG5cbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIGBjb21waWxlLXRpbWUta25vd24gaW50ZWdlciBvcGVyYXRpb24gb3V0c2lkZSBzaWduZWQgNjQtYml0ICR7c2NhbGFyfSByYW5nZWAsIGxvY2F0aW9uKVxuICB9XG4gIGlmICgobGFuZ3VhZ2UgPT0gXCJkYXJ0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJrb3RsaW5cIikgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuICAgICh2YWx1ZSA8IC1CaWdJbnQoTnVtYmVyLk1BWF9TQUZFX0lOVEVHRVIpIHx8IHZhbHVlID4gQmlnSW50KE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKSkpIHtcbiAgICB1bnN1cHBvcnRlZENhcGFiaWxpdHkobGFuZ3VhZ2UsIFwiY29tcGlsZS10aW1lLWtub3duIGludGVnZXIgb3BlcmF0aW9uIG91dHNpZGUgdGhlIFNlbWFudGlmb2xkIHNhZmUtaW50ZWdlciByYW5nZVwiLCBsb2NhdGlvbilcbiAgfVxufVxuXG4vKipcbiAqIEV2YWx1YXRlcyBvbmx5IGxpdGVyYWwgaW50ZWdlci1vcGVyYXRpb24gdHJlZXMgZm9yIGJvdW5kcyB2YWxpZGF0aW9uLCBuZXZlciBJUiBmb2xkaW5nLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtiaWdpbnQgfCB1bmRlZmluZWR9IEtub3duIG1hdGhlbWF0aWNhbCBpbnRlZ2VyLlxuICovXG5mdW5jdGlvbiBrbm93bkludGVnZXJWYWx1ZShleHByZXNzaW9uKSB7XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiICYmIE51bWJlci5pc1NhZmVJbnRlZ2VyKGV4cHJlc3Npb24udmFsdWUpKSByZXR1cm4gQmlnSW50KGV4cHJlc3Npb24udmFsdWUpXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIiAmJiBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkludGVnZXJOZWdhdGVcIikge1xuICAgIGNvbnN0IG9wZXJhbmQgPSBrbm93bkludGVnZXJWYWx1ZShleHByZXNzaW9uLm9wZXJhbmQpXG5cbiAgICByZXR1cm4gb3BlcmFuZCA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogLW9wZXJhbmRcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kICE9IFwiQmluYXJ5RXhwcmVzc2lvblwiKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgbGVmdCA9IGtub3duSW50ZWdlclZhbHVlKGV4cHJlc3Npb24ubGVmdClcbiAgY29uc3QgcmlnaHQgPSBrbm93bkludGVnZXJWYWx1ZShleHByZXNzaW9uLnJpZ2h0KVxuXG4gIGlmIChsZWZ0ID09PSB1bmRlZmluZWQgfHwgcmlnaHQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHVuZGVmaW5lZFxuICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyQWRkXCIpIHJldHVybiBsZWZ0ICsgcmlnaHRcbiAgaWYgKGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlclN1YnRyYWN0XCIpIHJldHVybiBsZWZ0IC0gcmlnaHRcbiAgaWYgKGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlck11bHRpcGx5XCIpIHJldHVybiBsZWZ0ICogcmlnaHRcblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogRW1pdHMgb25lIHJlY3Vyc2l2ZSBzZW1hbnRpYyB0eXBlIHdoaWxlIG1hcHBpbmcgZXZlcnkgY29uc3RpdHVlbnQgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IHR5cGUgLSBTZW1hbnRpYyB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBFeGFjdCB0eXBlIG9jY3VycmVuY2UgcGF0aC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVGV4dEJhY2tlbmRMYW5ndWFnZX0gbGFuZ3VhZ2UgLSBUYXJnZXQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtqYXZhQm94ZWRdIC0gV2hldGhlciBhIEphdmEgc2NhbGFyIGlzIGEgZ2VuZXJpYyBhcmd1bWVudC5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5leHBvcnQgZnVuY3Rpb24gZW1pdFR5cGUod3JpdGVyLCB0eXBlLCBwYXRoLCBsYW5ndWFnZSwgamF2YUJveGVkID0gZmFsc2UpIHtcbiAgaWYgKHR5cGUua2luZCA9PSBcIlR5cGVWYXJpYWJsZVJlZmVyZW5jZVwiKSB7XG4gICAgY29uc3QgcGFyYW1ldGVyID0gd3JpdGVyLnR5cGVQYXJhbWV0ZXJGb3JJZCh0eXBlLnBhcmFtZXRlcklkKVxuXG4gICAgd3JpdGVyLm1hcHBlZChwYXJhbWV0ZXIubmFtZSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5hbWU6IHBhcmFtZXRlci5uYW1lLCBub2RlOiB0eXBlLCBwYXRoLCByb2xlOiBcInR5cGVcIn0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIlJlY29yZFR5cGVcIikge1xuICAgIGNvbnN0IHJlY29yZCA9IHdyaXRlci5yZWNvcmRGb3JJZCh0eXBlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICB3cml0ZXIubWFwcGVkKHdyaXRlci5yZWNvcmROYW1lRm9ySWQodHlwZS5kZWNsYXJhdGlvbklkKSwge1xuICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbmFtZTogcmVjb3JkLm5hbWUsIG5vZGU6IHR5cGUsIHBhdGgsIHJvbGU6IFwidHlwZVwiXG4gICAgfSlcbiAgICBpZiAodHlwZS5hcmd1bWVudHMpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBcIltcIiA6IFwiPFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHR5cGUsIHBhdGh9KVxuICAgICAgdHlwZS5hcmd1bWVudHMuZm9yRWFjaCgoYXJndW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHdyaXRlci5zeW50aGV0aWMobGFuZ3VhZ2UgPT0gXCJwaHBcIiB8fCBsYW5ndWFnZSA9PSBcInJ1YnlcIiB8fCBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiLFwiIDogXCIsIFwiLFxuICAgICAgICAgIFwiZ2VuZXJpYyB0eXBlIGFyZ3VtZW50IHNlcGFyYXRvclwiLCBbdHlwZV0sIFtwYXRoXSlcbiAgICAgICAgZW1pdFR5cGUod3JpdGVyLCBhcmd1bWVudCwgYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YCwgbGFuZ3VhZ2UsIGxhbmd1YWdlID09IFwiamF2YVwiKVxuICAgICAgfSlcbiAgICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBcIl1cIiA6IFwiPlwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IHR5cGUsIHBhdGh9KVxuICAgIH1cbiAgICByZXR1cm5cbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSB3cml0ZXIuY2xhc3NGb3JJZCh0eXBlLmRlY2xhcmF0aW9uSWQpXG5cbiAgICB3cml0ZXIubWFwcGVkKHdyaXRlci5jbGFzc05hbWVGb3JJZCh0eXBlLmRlY2xhcmF0aW9uSWQpLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLCBuYW1lOiBkZWNsYXJhdGlvbi5uYW1lLCBub2RlOiB0eXBlLCBwYXRoLCByb2xlOiBcInR5cGVcIlxuICAgIH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHtcbiAgICBjb25zdCByZXNvdXJjZSA9IHdyaXRlci5yZXNvdXJjZUZvcklkKHR5cGUucmVzb3VyY2VJZClcbiAgICB3cml0ZXIubWFwcGVkKHdyaXRlci5jYXBhYmlsaXR5Tm9taW5hbE5hbWUocmVzb3VyY2UubmFtZSksIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBuYW1lOiByZXNvdXJjZS5uYW1lLCBub2RlOiB0eXBlLCBwYXRoLCByb2xlOiBcInR5cGVcIn0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKHR5cGUua2luZCA9PSBcIk93bmVkUmVmZXJlbmNlVHlwZVwiKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSB3cml0ZXIuY2xhc3NGb3JJZCh0eXBlLmRlY2xhcmF0aW9uSWQpXG4gICAgd3JpdGVyLm1hcHBlZCh3cml0ZXIuY2xhc3NOYW1lRm9ySWQodHlwZS5kZWNsYXJhdGlvbklkKSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5hbWU6IGRlY2xhcmF0aW9uLm5hbWUsIG5vZGU6IHR5cGUsIHBhdGgsIHJvbGU6IFwidHlwZVwifSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiKSB7XG4gICAgY29uc3Qgc3BlbGxpbmcgPSBsYW5ndWFnZSA9PSBcImphdmFcIiAmJiBqYXZhQm94ZWRcbiAgICAgID8gdHlwZS5uYW1lID09IFwiaW50ZWdlclwiID8gXCJJbnRlZ2VyXCIgOiB0eXBlLm5hbWUgPT0gXCJib29sZWFuXCIgPyBcIkJvb2xlYW5cIiA6IHR5cGUubmFtZSA9PSBcInN0cmluZ1wiID8gXCJTdHJpbmdcIiA6IFwidm9pZFwiXG4gICAgICA6IGVtaXRTY2FsYXJUeXBlKGxhbmd1YWdlLCB0eXBlKVxuXG4gICAgd3JpdGVyLm1hcHBlZChzcGVsbGluZywge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IHR5cGUsIHBhdGgsIHJvbGU6IFwidHlwZVwifSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAodHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICBjb25zdCBwcmVmaXggPSBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiamF2YS51dGlsLk9wdGlvbmFsPFwiIDogbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IFwiP1wiIDogXCJcIlxuXG4gICAgd3JpdGVyLm1hcHBlZChwcmVmaXgsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiB0eXBlLCBwYXRoLCByb2xlOiBcInR5cGVcIn0pXG4gICAgZW1pdFR5cGUod3JpdGVyLCB0eXBlLnZhbHVlVHlwZSwgYCR7cGF0aH0vdmFsdWVUeXBlYCwgbGFuZ3VhZ2UsIGxhbmd1YWdlID09IFwiamF2YVwiKVxuICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBcIj5cIiA6IGxhbmd1YWdlID09IFwicnVieVwiID8gXCI/XCIgOiBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiA/IFwifG51bGxcIiA6XG4gICAgICBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IFwiIHwgbnVsbFwiIDogXCJcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiB0eXBlLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuICBjb25zdCBwcmVmaXggPSB0eXBlLmtpbmQgPT0gXCJMaXN0VHlwZVwiXG4gICAgPyBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IFwiQXJyYXlbXCIgOiBsYW5ndWFnZSA9PSBcInBocFwiID8gXCJsaXN0PFwiIDpcbiAgICAgIGxhbmd1YWdlID09IFwiamF2YVwiID8gXCJqYXZhLnV0aWwuTGlzdDxcIiA6IFwiUmVhZG9ubHlBcnJheTxcIlxuICAgIDogbGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBcIkhhc2hbXCIgOiBsYW5ndWFnZSA9PSBcInBocFwiID8gXCJhcnJheTxcIiA6XG4gICAgICBsYW5ndWFnZSA9PSBcImphdmFcIiA/IHR5cGUua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIgPyBcImphdmEudXRpbC5TZXF1ZW5jZWRNYXA8XCIgOiBcImphdmEudXRpbC5NYXA8XCIgOiBcIlJlYWRvbmx5TWFwPFwiXG5cbiAgd3JpdGVyLm1hcHBlZChwcmVmaXgsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiB0eXBlLCBwYXRoLCByb2xlOiBcInR5cGVcIn0pXG4gIGlmICh0eXBlLmtpbmQgPT0gXCJMaXN0VHlwZVwiKSB7XG4gICAgZW1pdFR5cGUod3JpdGVyLCB0eXBlLmVsZW1lbnRUeXBlLCBgJHtwYXRofS9lbGVtZW50VHlwZWAsIGxhbmd1YWdlLCBsYW5ndWFnZSA9PSBcImphdmFcIilcbiAgfSBlbHNlIHtcbiAgICBlbWl0VHlwZSh3cml0ZXIsIHR5cGUua2V5VHlwZSwgYCR7cGF0aH0va2V5VHlwZWAsIGxhbmd1YWdlLCBsYW5ndWFnZSA9PSBcImphdmFcIilcbiAgICB3cml0ZXIuc3ludGhldGljKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiIHx8IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiID8gXCIsIFwiIDogXCIsXCIsIFwibWFwIHR5cGUgc2VwYXJhdG9yXCIsIFt0eXBlXSwgW3BhdGhdKVxuICAgIGVtaXRUeXBlKHdyaXRlciwgdHlwZS52YWx1ZVR5cGUsIGAke3BhdGh9L3ZhbHVlVHlwZWAsIGxhbmd1YWdlLCBsYW5ndWFnZSA9PSBcImphdmFcIilcbiAgfVxuICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwicnVieVwiID8gXCJdXCIgOiBcIj5cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiB0eXBlLCBwYXRofSlcbn1cblxuLyoqXG4gKiBFbWl0cyBhIHN1cHBvcnRlZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3dyaXRlci5qc1wiKS5Tb3VyY2VXcml0ZXJ9IHdyaXRlciAtIFNvdXJjZS1hd2FyZSB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhdGggLSBFeGFjdCBKU09OIFBvaW50ZXIgZm9yIHRoaXMgZXhwcmVzc2lvbiBvY2N1cnJlbmNlLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UZXh0QmFja2VuZExhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7KG5hbWU6IHN0cmluZykgPT4gc3RyaW5nfSBlbWl0SWRlbnRpZmllciAtIElkZW50aWZpZXIgZm9ybWF0dGVyLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24sIHBhdGgsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcikge1xuICBjb25zdCBlZmZlY3RUZW1wb3JhcnkgPSB3cml0ZXIuZWZmZWN0UmVwbGFjZW1lbnROYW1lKGV4cHJlc3Npb24pXG5cbiAgaWYgKGVmZmVjdFRlbXBvcmFyeSkge1xuICAgIHdyaXRlci5zeW50aGV0aWMoZW1pdElkZW50aWZpZXIoZWZmZWN0VGVtcG9yYXJ5KSwgXCJleGFjdGx5LW9uY2UgZWZmZWN0IHRlbXBvcmFyeSByZWFkXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSB7XG4gICAgd3JpdGVyLm1hcHBlZChlbWl0SWRlbnRpZmllcihleHByZXNzaW9uLm5hbWUpLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJuYW1lXCJ9KVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJSZWNlaXZlckV4cHJlc3Npb25cIikge1xuICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IFwiJHRoaXNcIiA6IGxhbmd1YWdlID09IFwicnVieVwiID8gXCJzZWxmXCIgOiBcInRoaXNcIixcbiAgICAgIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcInJlY2VpdmVyXCJ9KVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJPd25lZE1vdmVFeHByZXNzaW9uXCIgfHwgZXhwcmVzc2lvbi5raW5kID09IFwiT3duZWRCb3Jyb3dFeHByZXNzaW9uXCIpIHtcbiAgICBpZiAoZXhwcmVzc2lvbi5leHByZXNzaW9uLmtpbmQgPT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSB7XG4gICAgICB3cml0ZXIubWFwcGVkKGVtaXRJZGVudGlmaWVyKGV4cHJlc3Npb24uZXhwcmVzc2lvbi5uYW1lKSwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5hbWU6IGV4cHJlc3Npb24uZXhwcmVzc2lvbi5uYW1lLFxuICAgICAgICBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm5hbWVcIn0pXG4gICAgfSBlbHNlIGlmIChleHByZXNzaW9uLmV4cHJlc3Npb24ua2luZCA9PSBcIlJlY2VpdmVyRXhwcmVzc2lvblwiKSB7XG4gICAgICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwicGhwXCIgPyBcIiR0aGlzXCIgOiBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IFwic2VsZlwiIDogXCJ0aGlzXCIsXG4gICAgICAgIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcInJlY2VpdmVyXCJ9KVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBmaWVsZCA9IHdyaXRlci5wcml2YXRlRmllbGRGb3JJZChleHByZXNzaW9uLmV4cHJlc3Npb24uZmllbGQpXG5cbiAgICAgIGlmIChsYW5ndWFnZSAhPSBcInJ1YnlcIikge1xuICAgICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24uZXhwcmVzc2lvbi5yZWNlaXZlciwgYCR7cGF0aH0vZXhwcmVzc2lvbi9yZWNlaXZlcmAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICAgIH1cbiAgICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IGAtPiR7ZmllbGQubmFtZX1gIDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgPyBgLiMke2ZpZWxkLm5hbWV9YCA6XG4gICAgICAgIGxhbmd1YWdlID09IFwicnVieVwiID8gYEAke2ZpZWxkLm5hbWV9YCA6IGAuJHtmaWVsZC5uYW1lfWAsXG4gICAgICB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbmFtZTogZmllbGQubmFtZSwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJtZW1iZXJcIn0pXG4gICAgfVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiKSB7XG4gICAgY29uc3Qgc3BlbGxpbmcgPSBsYW5ndWFnZSA9PSBcImNzaGFycFwiIHx8IGxhbmd1YWdlID09IFwia290bGluXCIgPyBgJHtleHByZXNzaW9uLnZhbHVlfUxgIDogU3RyaW5nKGV4cHJlc3Npb24udmFsdWUpXG5cbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJsaXRlcmFsXCJ9KVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSB7XG4gICAgY29uc3Qgc3BlbGxpbmcgPSBsYW5ndWFnZSA9PSBcInB5dGhvblwiID8gZXhwcmVzc2lvbi52YWx1ZSA/IFwiVHJ1ZVwiIDogXCJGYWxzZVwiIDogZXhwcmVzc2lvbi52YWx1ZSA/IFwidHJ1ZVwiIDogXCJmYWxzZVwiXG5cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJkYXJ0XCIpIHtcbiAgICAgIHdyaXRlci5zeW50aGV0aWMoXCJfc2VtYW50aWZvbGRCb29sZWFuKFwiLCBcIkRhcnQgYW5hbHl6ZWQgQm9vbGVhbiBsaXRlcmFsXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIH1cbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJsaXRlcmFsXCJ9KVxuICAgIGlmIChsYW5ndWFnZSA9PSBcImRhcnRcIikgd3JpdGVyLnN5bnRoZXRpYyhcIilcIiwgXCJEYXJ0IGFuYWx5emVkIEJvb2xlYW4gbGl0ZXJhbFwiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiU3RyaW5nTGl0ZXJhbFwiKSB7XG4gICAgd3JpdGVyLm1hcHBlZChlbWl0U3RyaW5nTGl0ZXJhbChsYW5ndWFnZSwgZXhwcmVzc2lvbi52YWx1ZSksIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcImxpdGVyYWxcIn0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsTm9uZVwiKSB7XG4gICAgd3JpdGVyLm1hcHBlZChsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiamF2YS51dGlsLk9wdGlvbmFsLmVtcHR5KClcIiA6IGxhbmd1YWdlID09IFwicnVieVwiID8gXCJuaWxcIiA6IFwibnVsbFwiLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcImFic2VuY2VcIlxuICAgIH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSB7XG4gICAgaWYgKGxhbmd1YWdlID09IFwiamF2YVwiKSB7XG4gICAgICB3cml0ZXIubWFwcGVkKFwiamF2YS51dGlsLk9wdGlvbmFsLm9mKFwiLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJzb21lXCJ9KVxuICAgIH0gZWxzZSB7XG4gICAgICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJzb21lXCJ9KVxuICAgIH1cbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24udmFsdWUsIGAke3BhdGh9L3ZhbHVlYCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsSXNQcmVzZW50XCIpIHtcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJydWJ5XCIpIHdyaXRlci5tYXBwZWQoXCIhXCIsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm9wZXJhdG9yXCJ9KVxuICAgIGVsc2UgaWYgKGxhbmd1YWdlICE9IFwiamF2YVwiKSB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5vcGVyYW5kLCBgJHtwYXRofS9vcGVyYW5kYCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBcIi5pc1ByZXNlbnQoKVwiIDogbGFuZ3VhZ2UgPT0gXCJydWJ5XCIgPyBcIi5uaWw/XCIgOiBcIiAhPT0gbnVsbFwiLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm9wZXJhdG9yXCJcbiAgICB9KVxuICAgIGlmIChsYW5ndWFnZSAhPSBcInJ1YnlcIiAmJiBsYW5ndWFnZSAhPSBcImphdmFcIikgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxVbndyYXBcIikge1xuICAgIGlmIChsYW5ndWFnZSAhPSBcImphdmFcIikge1xuICAgICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwidW53cmFwXCJ9KVxuICAgIH1cbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhXCIpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQoXCIuZ2V0KClcIiwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwidW53cmFwXCJ9KVxuICAgIH0gZWxzZSB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIHJldHVyblxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJMaXN0TGl0ZXJhbFwiKSB7XG4gICAgd3JpdGVyLm1hcHBlZChsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiamF2YS51dGlsLkxpc3Qub2YoXCIgOiBcIltcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBleHByZXNzaW9uLmVsZW1lbnRzLmZvckVhY2goKGVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXgpIHdyaXRlci5zeW50aGV0aWMoXCIsIFwiLCBcImxpc3QgZWxlbWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGVsZW1lbnQsIGAke3BhdGh9L2VsZW1lbnRzLyR7aW5kZXh9YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIH0pXG4gICAgd3JpdGVyLm1hcHBlZChsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiKVwiIDogXCJdXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExpdGVyYWxcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKSB7XG4gICAgY29uc3Qgb3BlbiA9IGxhbmd1YWdlID09IFwiamF2YVwiID8gXCJqYXZhLnV0aWwuTWFwLm9mKFwiIDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyBcIm5ldyBNYXAoW1wiIDpcbiAgICAgIGxhbmd1YWdlID09IFwicGhwXCIgPyBcIltcIiA6IFwie1wiXG4gICAgY29uc3QgY2xvc2UgPSBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiKVwiIDogbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyBcIl0pXCIgOlxuICAgICAgbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IFwiXVwiIDogXCJ9XCJcblxuICAgIHdyaXRlci5tYXBwZWQob3Blbiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBleHByZXNzaW9uLmVudHJpZXMuZm9yRWFjaCgoZW50cnksIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBlbnRyeVBhdGggPSBgJHtwYXRofS9lbnRyaWVzLyR7aW5kZXh9YFxuXG4gICAgICBpZiAoaW5kZXgpIHdyaXRlci5zeW50aGV0aWMoXCIsIFwiLCBcIm1hcCBlbnRyeSBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgICBpZiAobGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIpIHdyaXRlci5tYXBwZWQoXCJbXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZW50cnksIHBhdGg6IGVudHJ5UGF0aH0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGVudHJ5LmtleSwgYCR7ZW50cnlQYXRofS9rZXlgLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwicnVieVwiID8gXCIgPT4gXCIgOiBsYW5ndWFnZSA9PSBcInBocFwiID8gXCIgPT4gXCIgOiBcIiwgXCIsIHtcbiAgICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZW50cnksIHBhdGg6IGVudHJ5UGF0aCwgcm9sZTogXCJvcGVyYXRvclwiXG4gICAgICB9KVxuICAgICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBlbnRyeS52YWx1ZSwgYCR7ZW50cnlQYXRofS92YWx1ZWAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICAgIGlmIChsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiB8fCBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIikgd3JpdGVyLm1hcHBlZChcIl1cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBlbnRyeSwgcGF0aDogZW50cnlQYXRofSlcbiAgICB9KVxuICAgIHdyaXRlci5tYXBwZWQoY2xvc2UsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkxpc3RJbmRleEV4cHJlc3Npb25cIikge1xuICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5jb2xsZWN0aW9uLCBgJHtwYXRofS9jb2xsZWN0aW9uYCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5tYXBwZWQobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBcIi5nZXQoXCIgOiBcIltcIiwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLmluZGV4LCBgJHtwYXRofS9pbmRleGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwiamF2YVwiID8gXCIpXCIgOiBcIl1cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWFwTG9va3VwRXhwcmVzc2lvblwiKSB7XG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLmNvbGxlY3Rpb24sIGAke3BhdGh9L2NvbGxlY3Rpb25gLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgY29uc3Qgb3BlcmF0b3IgPSBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IFwiLmZldGNoKFwiIDogbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IFwiW1wiIDogXCIuZ2V0KFwiXG5cbiAgICB3cml0ZXIubWFwcGVkKG9wZXJhdG9yLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwifSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ua2V5LCBgJHtwYXRofS9rZXlgLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgd3JpdGVyLm1hcHBlZChsYW5ndWFnZSA9PSBcInBocFwiID8gXCJdXCIgOiBcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIpIHtcbiAgICAgIHdyaXRlci5zeW50aGV0aWMoXCIhXCIsIFwic3RhdGljYWxseSBwcm92ZW4gbWFwIGxvb2t1cFwiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICB9XG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkNvbGxlY3Rpb25TaXplRXhwcmVzc2lvblwiKSB7XG4gICAgaWYgKGxhbmd1YWdlID09IFwicGhwXCIpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQoXCJjb3VudChcIiwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24uY29sbGVjdGlvbiwgYCR7cGF0aH0vY29sbGVjdGlvbmAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLmNvbGxlY3Rpb24sIGAke3BhdGh9L2NvbGxlY3Rpb25gLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgY29uc3Qgb3BlcmF0b3IgPSBsYW5ndWFnZSA9PSBcInJ1YnlcIiB8fCBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiLnNpemVcIiA6XG4gICAgICBleHByZXNzaW9uLmNvbGxlY3Rpb25LaW5kID09IFwibGlzdFwiID8gXCIubGVuZ3RoXCIgOiBcIi5zaXplXCJcblxuICAgIHdyaXRlci5tYXBwZWQoYCR7b3BlcmF0b3J9JHtsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiKClcIiA6IFwiXCJ9YCwge1xuICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwiXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGRhcnRNdWx0aWxpbmUgPSBsYW5ndWFnZSA9PSBcImRhcnRcIiAmJiBleHByZXNzaW9uLmFyZ3VtZW50cy5sZW5ndGggPiAwICYmXG4gICAgICBkYXJ0RXhwcmVzc2lvbkV4Y2VlZHNQYWdlV2lkdGgod3JpdGVyLCBleHByZXNzaW9uKVxuICAgIGNvbnN0IGRhcnRJbmRlbnQgPSBkYXJ0TXVsdGlsaW5lID8gY3VycmVudExpbmVJbmRlbnQod3JpdGVyKSA6IFwiXCJcblxuICAgIHdyaXRlci5tYXBwZWQod3JpdGVyLmNhbGxOYW1lRm9yKGV4cHJlc3Npb24pLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLCBuYW1lOiBleHByZXNzaW9uLmNhbGxlZSwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJjYWxsZWVcIlxuICAgIH0pXG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBleHByZXNzaW9uLmFyZ3VtZW50cy5mb3JFYWNoKChhcmd1bWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChkYXJ0TXVsdGlsaW5lKSB3cml0ZXIuc3ludGhldGljKGAke2luZGV4ID8gXCJcIiA6IFwiXFxuXCJ9JHtkYXJ0SW5kZW50fSAgYCwgXCJEYXJ0IGFyZ3VtZW50IGluZGVudGF0aW9uXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgICAgZWxzZSBpZiAoaW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJhcmd1bWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGFyZ3VtZW50LCBgJHtwYXRofS9hcmd1bWVudHMvJHtpbmRleH1gLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgICBpZiAoZGFydE11bHRpbGluZSkgd3JpdGVyLnN5bnRoZXRpYyhcIixcXG5cIiwgXCJEYXJ0IGZvcm1hdHRlciBhcmd1bWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgfSlcbiAgICBpZiAoZGFydE11bHRpbGluZSkgd3JpdGVyLnN5bnRoZXRpYyhkYXJ0SW5kZW50LCBcIkRhcnQgY2FsbCBjbG9zaW5nIGluZGVudGF0aW9uXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkVmZmVjdENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBvcGVyYXRpb24gPSB3cml0ZXIuZWZmZWN0T3BlcmF0aW9uRm9ySWQoZXhwcmVzc2lvbi5vcGVyYXRpb24pXG4gICAgaWYgKGxhbmd1YWdlID09IFwiamF2YVwiICYmIHdyaXRlci5yZWZlcmVuY2VDbGFzc0VtaXNzaW9uRGVwdGggPiAwKSB7XG4gICAgICB3cml0ZXIuc3ludGhldGljKFwiTWFpbi5cIiwgXCJwcm90ZWN0ZWQgVGFzayAwMzQgaG9zdCBzdXBwb3J0IG93bmVyXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIH1cbiAgICB3cml0ZXIubWFwcGVkKHdyaXRlci5zdGRsaWJQcm92aWRlckVudHJ5Rm9yKG9wZXJhdGlvbikgPz8gb3BlcmF0aW9uLm5hbWUsIHtcbiAgICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5hbWU6IG9wZXJhdGlvbi5uYW1lLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcImNhbGxlZVwiXG4gICAgfSlcbiAgICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIGV4cHJlc3Npb24uYXJndW1lbnRzLmZvckVhY2goKGFyZ3VtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ID4gMCkgd3JpdGVyLnN5bnRoZXRpYyhcIiwgXCIsIFwiZWZmZWN0IGFyZ3VtZW50IHNlcGFyYXRvclwiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgYXJndW1lbnQsIGAke3BhdGh9L2FyZ3VtZW50cy8ke2luZGV4fWAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiKSB7XG4gICAgY29uc3QgZGVjbGFyYXRpb24gPSB3cml0ZXIuY2xhc3NGb3JJZChleHByZXNzaW9uLnJlZmVyZW5jZS5kZWNsYXJhdGlvbklkKVxuICAgIGNvbnN0IG5hbWUgPSB3cml0ZXIuY2xhc3NOYW1lRm9ySWQoZXhwcmVzc2lvbi5yZWZlcmVuY2UuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCBwcmVmaXggPSBsYW5ndWFnZSA9PSBcInJ1YnlcIiA/IGAke25hbWV9Lm5ld2AgOiBgbmV3ICR7bmFtZX1gXG5cbiAgICB3cml0ZXIubWFwcGVkKHByZWZpeCwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5hbWU6IGRlY2xhcmF0aW9uLm5hbWUsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwiY2xhc3NcIn0pXG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBleHByZXNzaW9uLmFyZ3VtZW50cy5mb3JFYWNoKChhcmd1bWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmIChpbmRleCA+IDApIHdyaXRlci5zeW50aGV0aWMoXCIsIFwiLCBcImNvbnN0cnVjdG9yIGFyZ3VtZW50IHNlcGFyYXRvclwiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgYXJndW1lbnQsIGAke3BhdGh9L2FyZ3VtZW50cy8ke2luZGV4fWAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1ldGhvZENhbGxFeHByZXNzaW9uXCIpIHtcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ucmVjZWl2ZXIsIGAke3BhdGh9L3JlY2VpdmVyYCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIGNvbnN0IG1ldGhvZCA9IHdyaXRlci5tZXRob2RGb3JJZChleHByZXNzaW9uLm1ldGhvZClcblxuICAgIHdyaXRlci5tYXBwZWQoYCR7bGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IFwiLT5cIiA6IFwiLlwifSR7bWV0aG9kLm5hbWV9YCwge1xuICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbmFtZTogbWV0aG9kLm5hbWUsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwibWVtYmVyXCJcbiAgICB9KVxuICAgIHdyaXRlci5tYXBwZWQoXCIoXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaCgoYXJndW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJtZXRob2QgYXJndW1lbnQgc2VwYXJhdG9yXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBhcmd1bWVudCwgYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIH0pXG4gICAgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiUmVjb3JkQ29uc3RydWN0aW9uXCIpIHtcbiAgICBjb25zdCByZWNvcmQgPSB3cml0ZXIucmVjb3JkRm9ySWQoZXhwcmVzc2lvbi5yZWNvcmQuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCB0YXJnZXROYW1lID0gd3JpdGVyLnJlY29yZE5hbWVGb3JJZChleHByZXNzaW9uLnJlY29yZC5kZWNsYXJhdGlvbklkLCB0cnVlKVxuICAgIGNvbnN0IHByZWZpeCA9IGxhbmd1YWdlID09IFwicnVieVwiID8gYCR7dGFyZ2V0TmFtZX0ubmV3YCA6IGBuZXcgJHt0YXJnZXROYW1lfWBcblxuICAgIHdyaXRlci5tYXBwZWQocHJlZml4LCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbmFtZTogcmVjb3JkLm5hbWUsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwicmVjb3JkXCJ9KVxuICAgIGlmICgobGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgfHwgbGFuZ3VhZ2UgPT0gXCJqYXZhXCIpICYmIGV4cHJlc3Npb24ucmVjb3JkLmFyZ3VtZW50cykge1xuICAgICAgd3JpdGVyLm1hcHBlZChcIjxcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLnJlY29yZCwgcGF0aDogYCR7cGF0aH0vcmVjb3JkYH0pXG4gICAgICBleHByZXNzaW9uLnJlY29yZC5hcmd1bWVudHMuZm9yRWFjaCgoYXJndW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChpbmRleCA+IDApIHdyaXRlci5zeW50aGV0aWMobGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBcIixcIiA6IFwiLCBcIiwgXCJnZW5lcmljIGNvbnN0cnVjdGlvbiBhcmd1bWVudCBzZXBhcmF0b3JcIixcbiAgICAgICAgICBbZXhwcmVzc2lvbi5yZWNvcmRdLCBbYCR7cGF0aH0vcmVjb3JkYF0pXG4gICAgICAgIGVtaXRUeXBlKHdyaXRlciwgYXJndW1lbnQsIGAke3BhdGh9L3JlY29yZC9hcmd1bWVudHMvJHtpbmRleH1gLCBsYW5ndWFnZSwgbGFuZ3VhZ2UgPT0gXCJqYXZhXCIpXG4gICAgICB9KVxuICAgICAgd3JpdGVyLm1hcHBlZChcIj5cIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLnJlY29yZCwgcGF0aDogYCR7cGF0aH0vcmVjb3JkYH0pXG4gICAgfVxuICAgIHdyaXRlci5tYXBwZWQoXCIoXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaCgoYXJndW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggPiAwKSB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJyZWNvcmQgYXJndW1lbnQgc2VwYXJhdG9yXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBhcmd1bWVudCwgYCR7cGF0aH0vYXJndW1lbnRzLyR7aW5kZXh9YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIH0pXG4gICAgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSB7XG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLnJlY2VpdmVyLCBgJHtwYXRofS9yZWNlaXZlcmAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICBjb25zdCBmaWVsZCA9IHdyaXRlci5maWVsZEZvcklkKGV4cHJlc3Npb24uZmllbGQpXG4gICAgY29uc3QgcGhwR2VuZXJpY1JlY29yZCA9IGxhbmd1YWdlID09IFwicGhwXCIgJiZcbiAgICAgICh3cml0ZXIucmVjb3JkRm9yRmllbGRJZChleHByZXNzaW9uLmZpZWxkKS50eXBlUGFyYW1ldGVycz8ubGVuZ3RoID8/IDApID4gMFxuICAgIGNvbnN0IHNwZWxsaW5nID0gbGFuZ3VhZ2UgPT0gXCJwaHBcIiA/IGAtPiR7ZmllbGQubmFtZX0ke3BocEdlbmVyaWNSZWNvcmQgPyBcIigpXCIgOiBcIlwifWAgOlxuICAgICAgbGFuZ3VhZ2UgPT0gXCJqYXZhXCIgPyBgLiR7ZmllbGQubmFtZX0oKWAgOiBgLiR7ZmllbGQubmFtZX1gXG5cbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJtZW1iZXJcIn0pXG4gICAgcmV0dXJuXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlByaXZhdGVGaWVsZFJlYWRcIikge1xuICAgIGNvbnN0IGZpZWxkID0gd3JpdGVyLnByaXZhdGVGaWVsZEZvcklkKGV4cHJlc3Npb24uZmllbGQpXG5cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJydWJ5XCIpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQoYEAke2ZpZWxkLm5hbWV9YCwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5hbWU6IGZpZWxkLm5hbWUsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwibWVtYmVyXCJ9KVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5yZWNlaXZlciwgYCR7cGF0aH0vcmVjZWl2ZXJgLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgd3JpdGVyLm1hcHBlZChsYW5ndWFnZSA9PSBcInBocFwiID8gYC0+JHtmaWVsZC5uYW1lfWAgOiBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiA/IGAuIyR7ZmllbGQubmFtZX1gIDogYC4ke2ZpZWxkLm5hbWV9YCxcbiAgICAgIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBuYW1lOiBmaWVsZC5uYW1lLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm1lbWJlclwifSlcbiAgICByZXR1cm5cbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiRXJyb3JNZXNzYWdlUmVhZFwiKSB7XG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLnJlY2VpdmVyLCBgJHtwYXRofS9yZWNlaXZlcmAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwicGhwXCIgPyBcIi0+Z2V0TWVzc2FnZSgpXCIgOiBsYW5ndWFnZSA9PSBcImphdmFcIiA/IFwiLmdldE1lc3NhZ2UoKVwiIDogXCIubWVzc2FnZVwiLCB7XG4gICAgICBtYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm1lbWJlclwiXG4gICAgfSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikge1xuICAgIGlmIChsYW5ndWFnZSA9PSBcImRhcnRcIiAmJiBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkludGVnZXJOZWdhdGVcIikge1xuICAgICAgZW1pdERhcnRJbnRlZ2VySGVscGVyKHdyaXRlciwgZXhwcmVzc2lvbiwgcGF0aCwgXCJfc2VtYW50aWZvbGRJbnRlZ2VyTmVnYXRlXCIsIFtcbiAgICAgICAgW2V4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGBdXG4gICAgICBdKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChsYW5ndWFnZSA9PSBcImtvdGxpblwiICYmIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlck5lZ2F0ZVwiKSB7XG4gICAgICBlbWl0S290bGluSW50ZWdlckhlbHBlcih3cml0ZXIsIGV4cHJlc3Npb24sIHBhdGgsIFwic2VtYW50aWZvbGRfaW50ZWdlcl9uZWdhdGVcIiwgW1xuICAgICAgICBbZXhwcmVzc2lvbi5vcGVyYW5kLCBgJHtwYXRofS9vcGVyYW5kYF1cbiAgICAgIF0pXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGxhbmd1YWdlID09IFwiY3NoYXJwXCIgJiYgZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyTmVnYXRlXCIpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQoXCJjaGVja2VkKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgICAgd3JpdGVyLm1hcHBlZChcIi1cIiwge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gICAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICB3cml0ZXIubWFwcGVkKGxhbmd1YWdlID09IFwicHl0aG9uXCIgJiYgZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJCb29sZWFuTm90XCIgPyBcIm5vdCBcIiA6IHVuYXJ5T3BlcmF0aW9uU3ludGF4W2V4cHJlc3Npb24ub3BlcmF0aW9uXSwge1xuICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwiXG4gICAgfSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ub3BlcmFuZCwgYCR7cGF0aH0vb3BlcmFuZGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIHJldHVyblxuICB9XG5cbiAgaWYgKGxhbmd1YWdlID09IFwiZGFydFwiICYmIFtcIkludGVnZXJBZGRcIiwgXCJJbnRlZ2VyU3VidHJhY3RcIiwgXCJJbnRlZ2VyTXVsdGlwbHlcIl0uaW5jbHVkZXMoZXhwcmVzc2lvbi5vcGVyYXRpb24pKSB7XG4gICAgY29uc3QgaGVscGVyID0gZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyQWRkXCIgPyBcIl9zZW1hbnRpZm9sZEludGVnZXJBZGRcIiA6XG4gICAgICBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkludGVnZXJTdWJ0cmFjdFwiID8gXCJfc2VtYW50aWZvbGRJbnRlZ2VyU3VidHJhY3RcIiA6IFwiX3NlbWFudGlmb2xkSW50ZWdlck11bHRpcGx5XCJcblxuICAgIGVtaXREYXJ0SW50ZWdlckhlbHBlcih3cml0ZXIsIGV4cHJlc3Npb24sIHBhdGgsIGhlbHBlciwgW1xuICAgICAgW2V4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGBdLCBbZXhwcmVzc2lvbi5yaWdodCwgYCR7cGF0aH0vcmlnaHRgXVxuICAgIF0pXG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAobGFuZ3VhZ2UgPT0gXCJrb3RsaW5cIiAmJiBbXCJJbnRlZ2VyQWRkXCIsIFwiSW50ZWdlclN1YnRyYWN0XCIsIFwiSW50ZWdlck11bHRpcGx5XCJdLmluY2x1ZGVzKGV4cHJlc3Npb24ub3BlcmF0aW9uKSkge1xuICAgIGNvbnN0IGhlbHBlciA9IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlckFkZFwiID8gXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX2FkZFwiIDpcbiAgICAgIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlclN1YnRyYWN0XCIgPyBcInNlbWFudGlmb2xkX2ludGVnZXJfc3VidHJhY3RcIiA6IFwic2VtYW50aWZvbGRfaW50ZWdlcl9tdWx0aXBseVwiXG5cbiAgICBlbWl0S290bGluSW50ZWdlckhlbHBlcih3cml0ZXIsIGV4cHJlc3Npb24sIHBhdGgsIGhlbHBlciwgW1xuICAgICAgW2V4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGBdLCBbZXhwcmVzc2lvbi5yaWdodCwgYCR7cGF0aH0vcmlnaHRgXVxuICAgIF0pXG4gICAgcmV0dXJuXG4gIH1cblxuICBpZiAobGFuZ3VhZ2UgPT0gXCJjc2hhcnBcIiAmJiBbXCJJbnRlZ2VyQWRkXCIsIFwiSW50ZWdlclN1YnRyYWN0XCIsIFwiSW50ZWdlck11bHRpcGx5XCJdLmluY2x1ZGVzKGV4cHJlc3Npb24ub3BlcmF0aW9uKSkge1xuICAgIHdyaXRlci5tYXBwZWQoXCJjaGVja2VkKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5sZWZ0LCBgJHtwYXRofS9sZWZ0YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIgXCIsIFwib3BlcmF0b3Igc3BhY2luZ1wiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICB3cml0ZXIubWFwcGVkKGJpbmFyeU9wZXJhdGlvblNwZWxsaW5nKGV4cHJlc3Npb24ub3BlcmF0aW9uLCBsYW5ndWFnZSksIHtcbiAgICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIlxuICAgIH0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJvcGVyYXRvciBzcGFjaW5nXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5yaWdodCwgYCR7cGF0aH0vcmlnaHRgLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChsYW5ndWFnZSA9PSBcImphdmFcIiAmJiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdFcXVhbFwiIHx8IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nTm90RXF1YWxcIikpIHtcbiAgICBjb25zdCBjb21wb3NpdGVPcGVyYXRvciA9IGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nTm90RXF1YWxcIiAmJiB3cml0ZXIuaGFzUmFuZ2UoZXhwcmVzc2lvbiwgcGF0aCwgXCJlcXVhbGl0eU9wZXJhdG9yXCIpXG5cbiAgICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIGlmIChleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ05vdEVxdWFsXCIpIHtcbiAgICAgIHdyaXRlci5tYXBwZWQoXCIhXCIsIHttYXBwaW5nS2luZDogXCJleGFjdFwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRoLCByb2xlOiBcIm9wZXJhdG9yXCJ9KVxuICAgIH1cbiAgICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICAgIGVtaXRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5sZWZ0LCBgJHtwYXRofS9sZWZ0YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgd3JpdGVyLm1hcHBlZChcIi5lcXVhbHNcIiwge1xuICAgICAgbWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogY29tcG9zaXRlT3BlcmF0b3IgPyBcImVxdWFsaXR5T3BlcmF0b3JcIiA6IFwib3BlcmF0b3JcIlxuICAgIH0pXG4gICAgd3JpdGVyLm1hcHBlZChcIihcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ucmlnaHQsIGAke3BhdGh9L3JpZ2h0YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5tYXBwZWQoXCIpXCIsIHttYXBwaW5nS2luZDogXCJhbmNob3JcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aH0pXG4gICAgd3JpdGVyLm1hcHBlZChcIilcIiwge21hcHBpbmdLaW5kOiBcImFuY2hvclwiLCBub2RlOiBleHByZXNzaW9uLCBwYXRofSlcbiAgICByZXR1cm5cbiAgfVxuXG4gIGlmIChsYW5ndWFnZSA9PSBcInN3aWZ0XCIgJiYgKGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiU3RyaW5nRXF1YWxcIiB8fCBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ05vdEVxdWFsXCIpKSB7XG4gICAgd3JpdGVyLm1hcHBlZChleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIlN0cmluZ0VxdWFsXCIgPyBcInNlbWFudGlmb2xkX3N0cmluZ19lcXVhbFwiIDogXCJzZW1hbnRpZm9sZF9zdHJpbmdfbm90X2VxdWFsXCIsIHtcbiAgICAgIG1hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIlxuICAgIH0pXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIihcIiwgXCJTd2lmdCBzY2FsYXItZXF1YWxpdHkgaGVscGVyIGNhbGxcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uLmxlZnQsIGAke3BhdGh9L2xlZnRgLCBsYW5ndWFnZSwgZW1pdElkZW50aWZpZXIpXG4gICAgd3JpdGVyLnN5bnRoZXRpYyhcIiwgXCIsIFwiU3dpZnQgc2NhbGFyLWVxdWFsaXR5IGFyZ3VtZW50IHNlcGFyYXRvclwiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ucmlnaHQsIGAke3BhdGh9L3JpZ2h0YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICAgIHdyaXRlci5zeW50aGV0aWMoXCIpXCIsIFwiU3dpZnQgc2NhbGFyLWVxdWFsaXR5IGhlbHBlciBjYWxsXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIHJldHVyblxuICB9XG5cbiAgY29uc3QgZGFydE11bHRpbGluZSA9IGxhbmd1YWdlID09IFwiZGFydFwiICYmIGRhcnRFeHByZXNzaW9uRXhjZWVkc1BhZ2VXaWR0aCh3cml0ZXIsIGV4cHJlc3Npb24pXG4gIGNvbnN0IGRhcnRJbmRlbnQgPSBkYXJ0TXVsdGlsaW5lID8gY3VycmVudExpbmVJbmRlbnQod3JpdGVyKSA6IFwiXCJcblxuICB3cml0ZXIubWFwcGVkKFwiKFwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxuICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ubGVmdCwgYCR7cGF0aH0vbGVmdGAsIGxhbmd1YWdlLCBlbWl0SWRlbnRpZmllcilcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIiBcIiwgXCJvcGVyYXRvciBzcGFjaW5nXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICBjb25zdCBzcGVsbGluZyA9IGJpbmFyeU9wZXJhdGlvblNwZWxsaW5nKGV4cHJlc3Npb24ub3BlcmF0aW9uLCBsYW5ndWFnZSlcblxuICBpZiAoZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJTdHJpbmdOb3RFcXVhbFwiICYmIHdyaXRlci5oYXNSYW5nZShleHByZXNzaW9uLCBwYXRoLCBcImVxdWFsaXR5T3BlcmF0b3JcIikpIHtcbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLnNsaWNlKDAsIDEpLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwifSlcbiAgICB3cml0ZXIubWFwcGVkKHNwZWxsaW5nLnNsaWNlKDEpLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJlcXVhbGl0eU9wZXJhdG9yXCJ9KVxuICB9IGVsc2Ugd3JpdGVyLm1hcHBlZChzcGVsbGluZywge21hcHBpbmdLaW5kOiBcImV4YWN0XCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGgsIHJvbGU6IFwib3BlcmF0b3JcIn0pXG4gIHdyaXRlci5zeW50aGV0aWMoZGFydE11bHRpbGluZSA/IGBcXG4ke2RhcnRJbmRlbnR9ICAgIGAgOiBcIiBcIiwgXCJvcGVyYXRvciBzcGFjaW5nXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICBlbWl0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ucmlnaHQsIGAke3BhdGh9L3JpZ2h0YCwgbGFuZ3VhZ2UsIGVtaXRJZGVudGlmaWVyKVxuICB3cml0ZXIubWFwcGVkKFwiKVwiLCB7bWFwcGluZ0tpbmQ6IFwiYW5jaG9yXCIsIG5vZGU6IGV4cHJlc3Npb24sIHBhdGh9KVxufVxuXG4vKipcbiAqIEVtaXRzIGEgS290bGluIGNoZWNrZWQtaW50ZWdlciBoZWxwZXIgd2hpbGUgcHJlc2VydmluZyB0aGUgc2VtYW50aWMgb3BlcmF0b3IgcmFuZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIC0gU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVW5hcnlFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmluYXJ5RXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIE9wZXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gT3BlcmF0aW9uIHBhdGguXG4gKiBAcGFyYW0ge3N0cmluZ30gaGVscGVyIC0gRXhhY3QgdGFyZ2V0IGhlbHBlci5cbiAqIEBwYXJhbSB7W2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb24sIHN0cmluZ11bXX0gb3BlcmFuZHMgLSBPcmRlcmVkIG9wZXJhbmRzIGFuZCBwYXRocy5cbiAqL1xuZnVuY3Rpb24gZW1pdEtvdGxpbkludGVnZXJIZWxwZXIod3JpdGVyLCBleHByZXNzaW9uLCBwYXRoLCBoZWxwZXIsIG9wZXJhbmRzKSB7XG4gIHdyaXRlci5tYXBwZWQoaGVscGVyLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwifSlcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIihcIiwgXCJLb3RsaW4gY2hlY2tlZC1pbnRlZ2VyIGhlbHBlciBjYWxsXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICBvcGVyYW5kcy5mb3JFYWNoKChbb3BlcmFuZCwgb3BlcmFuZFBhdGhdLCBpbmRleCkgPT4ge1xuICAgIGlmIChpbmRleCkgd3JpdGVyLnN5bnRoZXRpYyhcIiwgXCIsIFwiS290bGluIGNoZWNrZWQtaW50ZWdlciBhcmd1bWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBvcGVyYW5kLCBvcGVyYW5kUGF0aCwgXCJrb3RsaW5cIiwgaWRlbnRpdHlJZGVudGlmaWVyKVxuICB9KVxuICB3cml0ZXIuc3ludGhldGljKFwiKVwiLCBcIktvdGxpbiBjaGVja2VkLWludGVnZXIgaGVscGVyIGNhbGxcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG59XG5cbi8qKlxuICogRW1pdHMgYSBjb21waWxlci1vd25lZCBEYXJ0IGNoZWNrZWQtaW50ZWdlciBoZWxwZXIgY2FsbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi93cml0ZXIuanNcIikuU291cmNlV3JpdGVyfSB3cml0ZXIgU291cmNlLWF3YXJlIHdyaXRlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVW5hcnlFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmluYXJ5RXhwcmVzc2lvbn0gZXhwcmVzc2lvbiBPcGVyYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBPcGVyYXRpb24gcGF0aC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBoZWxwZXIgRXhhY3QgdGFyZ2V0IGhlbHBlci5cbiAqIEBwYXJhbSB7W2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb24sIHN0cmluZ11bXX0gb3BlcmFuZHMgT3JkZXJlZCBvcGVyYW5kcyBhbmQgcGF0aHMuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gZW1pdERhcnRJbnRlZ2VySGVscGVyKHdyaXRlciwgZXhwcmVzc2lvbiwgcGF0aCwgaGVscGVyLCBvcGVyYW5kcykge1xuICBjb25zdCBmbGF0TGVuZ3RoID0gaGVscGVyLmxlbmd0aCArIDIgKyBvcGVyYW5kcy5yZWR1Y2UoKHRvdGFsLCBbb3BlcmFuZF0sIGluZGV4KSA9PlxuICAgIHRvdGFsICsgZmxhdERhcnRFeHByZXNzaW9uKHdyaXRlciwgb3BlcmFuZCkubGVuZ3RoICsgKGluZGV4ID8gMiA6IDApLCAwKVxuICBjb25zdCBtdWx0aWxpbmUgPSB3cml0ZXIuY29sdW1uIC0gMSArIGZsYXRMZW5ndGggPiA4MFxuICBjb25zdCBpbmRlbnQgPSBtdWx0aWxpbmUgPyBjdXJyZW50TGluZUluZGVudCh3cml0ZXIpIDogXCJcIlxuXG4gIHdyaXRlci5tYXBwZWQoaGVscGVyLCB7bWFwcGluZ0tpbmQ6IFwiZXhhY3RcIiwgbm9kZTogZXhwcmVzc2lvbiwgcGF0aCwgcm9sZTogXCJvcGVyYXRvclwifSlcbiAgd3JpdGVyLnN5bnRoZXRpYyhcIihcIiwgXCJEYXJ0IGNoZWNrZWQtaW50ZWdlciBoZWxwZXIgY2FsbFwiLCBbZXhwcmVzc2lvbl0sIFtwYXRoXSlcbiAgb3BlcmFuZHMuZm9yRWFjaCgoW29wZXJhbmQsIG9wZXJhbmRQYXRoXSwgaW5kZXgpID0+IHtcbiAgICBpZiAobXVsdGlsaW5lKSB3cml0ZXIuc3ludGhldGljKGAke2luZGV4ID8gXCJcIiA6IFwiXFxuXCJ9JHtpbmRlbnR9ICBgLCBcIkRhcnQgY2hlY2tlZC1pbnRlZ2VyIGFyZ3VtZW50IGluZGVudGF0aW9uXCIsIFtleHByZXNzaW9uXSwgW3BhdGhdKVxuICAgIGVsc2UgaWYgKGluZGV4KSB3cml0ZXIuc3ludGhldGljKFwiLCBcIiwgXCJEYXJ0IGNoZWNrZWQtaW50ZWdlciBhcmd1bWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gICAgZW1pdEV4cHJlc3Npb24od3JpdGVyLCBvcGVyYW5kLCBvcGVyYW5kUGF0aCwgXCJkYXJ0XCIsIGlkZW50aXR5SWRlbnRpZmllcilcbiAgICBpZiAobXVsdGlsaW5lKSB3cml0ZXIuc3ludGhldGljKFwiLFxcblwiLCBcIkRhcnQgZm9ybWF0dGVyIGNoZWNrZWQtaW50ZWdlciBhcmd1bWVudCBzZXBhcmF0b3JcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gIH0pXG4gIGlmIChtdWx0aWxpbmUpIHdyaXRlci5zeW50aGV0aWMoaW5kZW50LCBcIkRhcnQgY2hlY2tlZC1pbnRlZ2VyIGNsb3NpbmcgaW5kZW50YXRpb25cIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG4gIHdyaXRlci5zeW50aGV0aWMoXCIpXCIsIFwiRGFydCBjaGVja2VkLWludGVnZXIgaGVscGVyIGNhbGxcIiwgW2V4cHJlc3Npb25dLCBbcGF0aF0pXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIERhcnQncyBkZWZhdWx0IDgwLWNvbHVtbiBmb3JtYXR0ZXIgbXVzdCBzcGxpdCBhbiBleHByZXNzaW9uIGF0IHRoZSBjdXJyZW50IHNpdGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIFNvdXJjZS1hd2FyZSB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBmbGF0IGV4cHJlc3Npb24gY3Jvc3NlcyB0aGUgZm9ybWF0dGVyIGJvdW5kYXJ5LlxuICovXG5mdW5jdGlvbiBkYXJ0RXhwcmVzc2lvbkV4Y2VlZHNQYWdlV2lkdGgod3JpdGVyLCBleHByZXNzaW9uKSB7XG4gIHJldHVybiB3cml0ZXIuY29sdW1uIC0gMSArIGZsYXREYXJ0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24pLmxlbmd0aCA+IDgwXG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY3VycmVudCBnZW5lcmF0ZWQgbGluZSdzIHN0cnVjdHVyYWwgaW5kZW50YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIFNvdXJjZS1hd2FyZSB3cml0ZXIuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBMZWFkaW5nIHNwYWNlcy5cbiAqL1xuZnVuY3Rpb24gY3VycmVudExpbmVJbmRlbnQod3JpdGVyKSB7XG4gIHJldHVybiAvXiAqL3UuZXhlYyh3cml0ZXIuY29kZS5zbGljZSh3cml0ZXIuY29kZS5sYXN0SW5kZXhPZihcIlxcblwiKSArIDEpKT8uWzBdID8/IFwiXCJcbn1cblxuLyoqXG4gKiBSZW5kZXJzIHRoZSBib3VuZGVkIFRhc2stMDA1IERhcnQgZXhwcmVzc2lvbiBwcm9maWxlIHdpdGhvdXQgbWFwcGluZ3MgZm9yIHBhZ2Utd2lkdGggcGxhbm5pbmcuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vd3JpdGVyLmpzXCIpLlNvdXJjZVdyaXRlcn0gd3JpdGVyIFNvdXJjZS1hd2FyZSB3cml0ZXIuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IGV4cHJlc3Npb24gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IEZsYXQgY2Fub25pY2FsIHNwZWxsaW5nLlxuICovXG5mdW5jdGlvbiBmbGF0RGFydEV4cHJlc3Npb24od3JpdGVyLCBleHByZXNzaW9uKSB7XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSByZXR1cm4gZXhwcmVzc2lvbi5uYW1lXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiKSByZXR1cm4gU3RyaW5nKGV4cHJlc3Npb24udmFsdWUpXG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSByZXR1cm4gYF9zZW1hbnRpZm9sZEJvb2xlYW4oJHtleHByZXNzaW9uLnZhbHVlID8gXCJ0cnVlXCIgOiBcImZhbHNlXCJ9KWBcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlN0cmluZ0xpdGVyYWxcIikgcmV0dXJuIGVtaXRTdHJpbmdMaXRlcmFsKFwiZGFydFwiLCBleHByZXNzaW9uLnZhbHVlKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBgJHt3cml0ZXIuY2FsbE5hbWVGb3IoZXhwcmVzc2lvbil9KCR7ZXhwcmVzc2lvbi5hcmd1bWVudHMubWFwKChhcmd1bWVudCkgPT5cbiAgICAgIGZsYXREYXJ0RXhwcmVzc2lvbih3cml0ZXIsIGFyZ3VtZW50KSkuam9pbihcIiwgXCIpfSlgXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3Qgb3BlcmFuZCA9IGZsYXREYXJ0RXhwcmVzc2lvbih3cml0ZXIsIGV4cHJlc3Npb24ub3BlcmFuZClcblxuICAgIHJldHVybiBleHByZXNzaW9uLm9wZXJhdGlvbiA9PSBcIkludGVnZXJOZWdhdGVcIiA/IGBfc2VtYW50aWZvbGRJbnRlZ2VyTmVnYXRlKCR7b3BlcmFuZH0pYCA6IGAoISR7b3BlcmFuZH0pYFxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHtcbiAgICBjb25zdCBsZWZ0ID0gZmxhdERhcnRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5sZWZ0KVxuICAgIGNvbnN0IHJpZ2h0ID0gZmxhdERhcnRFeHByZXNzaW9uKHdyaXRlciwgZXhwcmVzc2lvbi5yaWdodClcblxuICAgIGlmIChbXCJJbnRlZ2VyQWRkXCIsIFwiSW50ZWdlclN1YnRyYWN0XCIsIFwiSW50ZWdlck11bHRpcGx5XCJdLmluY2x1ZGVzKGV4cHJlc3Npb24ub3BlcmF0aW9uKSkge1xuICAgICAgY29uc3QgaGVscGVyID0gZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyQWRkXCIgPyBcIl9zZW1hbnRpZm9sZEludGVnZXJBZGRcIiA6XG4gICAgICAgIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlclN1YnRyYWN0XCIgPyBcIl9zZW1hbnRpZm9sZEludGVnZXJTdWJ0cmFjdFwiIDogXCJfc2VtYW50aWZvbGRJbnRlZ2VyTXVsdGlwbHlcIlxuXG4gICAgICByZXR1cm4gYCR7aGVscGVyfSgke2xlZnR9LCAke3JpZ2h0fSlgXG4gICAgfVxuICAgIHJldHVybiBgKCR7bGVmdH0gJHtiaW5hcnlPcGVyYXRpb25TcGVsbGluZyhleHByZXNzaW9uLm9wZXJhdGlvbiwgXCJkYXJ0XCIpfSAke3JpZ2h0fSlgXG4gIH1cbiAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVuc3VwcG9ydGVkIERhcnQgZXhwcmVzc2lvbiByZWFjaGVkIGZvcm1hdHRlciBwbGFubmluZyBhZnRlciBwcmVmbGlnaHQuXCIpXG59XG5cbi8qKlxuICogUHJlc2VydmVzIGEgS290bGluIGlkZW50aWZpZXIgc3BlbGxpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIElkZW50aWZpZXIgc3BlbGxpbmcuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBVbmNoYW5nZWQgc3BlbGxpbmcuXG4gKi9cbmZ1bmN0aW9uIGlkZW50aXR5SWRlbnRpZmllcihuYW1lKSB7XG4gIHJldHVybiBuYW1lXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIEphdmFTY3JpcHQtZmFtaWx5IGV4ZWN1dGlvbiBjYW4gY3JlYXRlIElFRUUtNzU0IHNpZ25lZCB6ZXJvLlxuICogU2VtYW50aWZvbGQgaW50ZWdlcnMgaGF2ZSBvbmUgbWF0aGVtYXRpY2FsIHplcm8sIHNvIHRob3NlIHRhcmdldHMgY2Fub25pY2FsaXplXG4gKiB0aGVpciBvYnNlcnZhYmxlIHNjYWxhciBvdXRwdXQgd2l0aG91dCBjaGFuZ2luZyB0aGUgb3BlcmF0aW9uIHRyZWUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBtb2R1bGUgLSBWYWxpZGF0ZWQgc2VtYW50aWMgbW9kdWxlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgY2Fub25pY2FsIG91dHB1dCByZW5kZXJpbmcgaXMgcmVxdWlyZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlc0Nhbm9uaWNhbFplcm9SZW5kZXJpbmcobW9kdWxlKSB7XG4gIHJldHVybiBtb2R1bGUuZnVuY3Rpb25zLnNvbWUoKGRlY2xhcmF0aW9uKSA9PiBibG9ja0NvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihkZWNsYXJhdGlvbi5ib2R5KSkgfHxcbiAgICBibG9ja0NvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihtb2R1bGUuZW50cnlQb2ludC5ib2R5KVxufVxuXG4vKipcbiAqIENoZWNrcyBvbmUgYmxvY2sgZm9yIHNpZ24tcHJvZHVjaW5nIGludGVnZXIgb3BlcmF0aW9ucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gU2VtYW50aWMgYmxvY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciBhIG5lc3RlZCBleHByZXNzaW9uIGNhbiBwcm9kdWNlIHNpZ25lZCB6ZXJvIGluIEphdmFTY3JpcHQuXG4gKi9cbmZ1bmN0aW9uIGJsb2NrQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGJsb2NrKSB7XG4gIHJldHVybiBibG9jay5zdGF0ZW1lbnRzLnNvbWUoKHN0YXRlbWVudCkgPT4ge1xuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKHN0YXRlbWVudC5jb25kaXRpb24pIHx8XG4gICAgICAgIGJsb2NrQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKHN0YXRlbWVudC5jb25zZXF1ZW50KSB8fFxuICAgICAgICBCb29sZWFuKHN0YXRlbWVudC5hbHRlcm5hdGUgJiYgYmxvY2tDb250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50LmFsdGVybmF0ZSkpXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkZvckVhY2hTdGF0ZW1lbnRcIikge1xuICAgICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50Lmxpc3QpIHx8IGJsb2NrQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKHN0YXRlbWVudC5ib2R5KVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIpIHtcbiAgICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKHN0YXRlbWVudC5tYXApIHx8IGJsb2NrQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKHN0YXRlbWVudC5ib2R5KVxuICAgIH1cbiAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJXaGlsZVN0YXRlbWVudFwiKSB7XG4gICAgICByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuY29uZGl0aW9uKSB8fCBibG9ja0NvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuYm9keSlcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiVHJ5U3RhdGVtZW50XCIpIHtcbiAgICAgIHJldHVybiBibG9ja0NvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuYm9keSkgfHwgYmxvY2tDb250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50LmNhdGNoQm9keSlcbiAgICB9XG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiUmFpc2VTdGF0ZW1lbnRcIikgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50LmVycm9yLm1lc3NhZ2UpXG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihzdGF0ZW1lbnQuaW5pdGlhbGl6ZXIpXG4gICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oc3RhdGVtZW50LmV4cHJlc3Npb24pXG4gICAgfVxuICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlJldHVyblN0YXRlbWVudFwiKSB7XG4gICAgICByZXR1cm4gQm9vbGVhbihzdGF0ZW1lbnQuZXhwcmVzc2lvbiAmJiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKHN0YXRlbWVudC5leHByZXNzaW9uKSlcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2VcbiAgfSlcbn1cblxuLyoqXG4gKiBDaGVja3Mgb25lIGV4cHJlc3Npb24gdHJlZSBmb3Igc2lnbi1wcm9kdWNpbmcgaW50ZWdlciBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBleHByZXNzaW9uIC0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoaXMgdHJlZSBjb250YWlucyBpbnRlZ2VyIG5lZ2F0aW9uIG9yIG11bHRpcGxpY2F0aW9uLlxuICovXG5mdW5jdGlvbiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24pIHtcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb24ub3BlcmF0aW9uID09IFwiSW50ZWdlck5lZ2F0ZVwiIHx8IGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oZXhwcmVzc2lvbi5vcGVyYW5kKVxuICB9XG4gIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIpIHtcbiAgICByZXR1cm4gZXhwcmVzc2lvbi5vcGVyYXRpb24gPT0gXCJJbnRlZ2VyTXVsdGlwbHlcIiB8fCBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24ubGVmdCkgfHxcbiAgICAgIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oZXhwcmVzc2lvbi5yaWdodClcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uLmFyZ3VtZW50cy5zb21lKChhcmd1bWVudCkgPT4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihhcmd1bWVudCkpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlJlY29yZENvbnN0cnVjdGlvblwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb24uYXJndW1lbnRzLnNvbWUoKGFyZ3VtZW50KSA9PiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGFyZ3VtZW50KSlcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTWVtYmVyUmVhZFwiKSByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihleHByZXNzaW9uLnJlY2VpdmVyKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdExpdGVyYWxcIikgcmV0dXJuIGV4cHJlc3Npb24uZWxlbWVudHMuc29tZSgoZWxlbWVudCkgPT4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihlbGVtZW50KSlcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExpdGVyYWxcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb24uZW50cmllcy5zb21lKChlbnRyeSkgPT4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihlbnRyeS5rZXkpIHx8XG4gICAgICBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGVudHJ5LnZhbHVlKSlcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiTGlzdEluZGV4RXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oZXhwcmVzc2lvbi5jb2xsZWN0aW9uKSB8fCBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24uaW5kZXgpXG4gIH1cbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24uY29sbGVjdGlvbikgfHwgZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihleHByZXNzaW9uLmtleSlcbiAgfVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ29sbGVjdGlvblNpemVFeHByZXNzaW9uXCIpIHJldHVybiBleHByZXNzaW9uQ29udGFpbnNTaWduUHJvZHVjaW5nT3BlcmF0aW9uKGV4cHJlc3Npb24uY29sbGVjdGlvbilcbiAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIk9wdGlvbmFsU29tZVwiKSByZXR1cm4gZXhwcmVzc2lvbkNvbnRhaW5zU2lnblByb2R1Y2luZ09wZXJhdGlvbihleHByZXNzaW9uLnZhbHVlKVxuICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiT3B0aW9uYWxJc1ByZXNlbnRcIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJPcHRpb25hbFVud3JhcFwiKSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb25Db250YWluc1NpZ25Qcm9kdWNpbmdPcGVyYXRpb24oZXhwcmVzc2lvbi5vcGVyYW5kKVxuICB9XG5cbiAgcmV0dXJuIGZhbHNlXG59XG5cbi8qKlxuICogTWFwcyBvbmUgYWxyZWFkeSB2YWxpZGF0ZWQgc2VtYW50aWMgb3BlcmF0aW9uIHRvIHRhcmdldCBzeW50YXguXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljQmluYXJ5T3BlcmF0aW9ufSBvcGVyYXRpb24gLSBDbG9zZWQgc2VtYW50aWMgb3BlcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0xhbmd1YWdlfSBsYW5ndWFnZSAtIFRhcmdldCBsYW5ndWFnZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFRhcmdldCBvcGVyYXRvciBzcGVsbGluZy5cbiAqL1xuZnVuY3Rpb24gYmluYXJ5T3BlcmF0aW9uU3BlbGxpbmcob3BlcmF0aW9uLCBsYW5ndWFnZSkge1xuICBjb25zdCBzeW50YXggPSBiaW5hcnlPcGVyYXRpb25TeW50YXhbb3BlcmF0aW9uXVxuXG4gIGlmIChsYW5ndWFnZSA9PSBcInBocFwiICYmIHN5bnRheC5waHApIHJldHVybiBzeW50YXgucGhwXG4gIGlmIChsYW5ndWFnZSA9PSBcInB5dGhvblwiICYmIHN5bnRheC5weXRob24pIHJldHVybiBzeW50YXgucHl0aG9uXG4gIGlmICgobGFuZ3VhZ2UgPT0gXCJwaHBcIiB8fCBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiB8fCBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIikgJiYgc3ludGF4LnN0cmljdCkgcmV0dXJuIHN5bnRheC5zdHJpY3RcblxuICByZXR1cm4gc3ludGF4LmRlZmF1bHRcbn1cbiJdfQ==
|