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
|
@@ -2,11 +2,16 @@
|
|
|
2
2
|
import PhpParser from "php-parser";
|
|
3
3
|
import { parse as parseComment } from "comment-parser";
|
|
4
4
|
import { missingType, parseFailure, unsupportedSyntax } from "../diagnostic.js";
|
|
5
|
+
import { blockReferencesProtectedEntry } from "../semantic/effects.js";
|
|
5
6
|
import { locationFromOffsets, moduleLocation } from "../semantic/location.js";
|
|
6
7
|
import { withAdaptedOperation } from "../semantic/operators.js";
|
|
7
8
|
import { withParserRanges } from "../semantic/provenance.js";
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
9
|
+
import { isTask034ResourceProbe } from "../semantic/capabilities.js";
|
|
10
|
+
import { hasExactEffectSupport } from "../backends/effects.js";
|
|
11
|
+
import { hasOnlyUnicodeScalars, scalarType } from "../semantic/scalars.js";
|
|
12
|
+
import { typeContainsAnyVariable } from "../semantic/generics.js";
|
|
13
|
+
import { requireSourceReturnType, requireSourceScalarType, sourceScalarType } from "./scalars.js";
|
|
14
|
+
import { capabilityFunctionSignatures, documentedValueType, instantiatedRecordFieldType, iterationBindingType, iterationOperandType, knownCallParameterTypes, knownCallReturnType, optionalType, orderedMapTypeFromMap, ownedResourceType, preservesGenericOptionalEvidence, recordType, referenceType, sameValueType } from "./types.js";
|
|
10
15
|
const parser = new PhpParser.Engine({
|
|
11
16
|
ast: { withPositions: true },
|
|
12
17
|
parser: { extractDoc: true, suppressErrors: false }
|
|
@@ -29,6 +34,29 @@ const phpBinaryOperations = new Map([
|
|
|
29
34
|
[">=", "GreaterThanOrEqual"],
|
|
30
35
|
[".", "StringConcat"]
|
|
31
36
|
]);
|
|
37
|
+
/**
|
|
38
|
+
* @typedef PhpConversionContext
|
|
39
|
+
* @property {Map<string, import("../semantic/types.js").SemanticBindingType>} bindings - Explicitly typed visible bindings.
|
|
40
|
+
* @property {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
|
|
41
|
+
* @property {import("../semantic/types.js").ClassDeclaration} [currentClass] - Enclosing reference class.
|
|
42
|
+
* @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
|
|
43
|
+
* @property {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Error declarations by identity.
|
|
44
|
+
* @property {Map<string, PhpFunctionSignature>} functions - Explicit module function signatures.
|
|
45
|
+
* @property {Set<object>} [orderedMapDeclarations] - Exact local declarations selected by parser-owned pair iteration.
|
|
46
|
+
* @property {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
|
|
47
|
+
* @property {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
|
|
48
|
+
* @property {import("../semantic/types.js").SemanticFunctionReturnType | undefined} returnType - Enclosing return type.
|
|
49
|
+
* @property {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
50
|
+
*/
|
|
51
|
+
/**
|
|
52
|
+
* @typedef PhpFunctionSignature
|
|
53
|
+
* @property {import("../semantic/types.js").SourceLocation} location - Complete declaration location.
|
|
54
|
+
* @property {import("../semantic/types.js").SourceLocation} nameLocation - Parser-owned name location.
|
|
55
|
+
* @property {string} name - Function name.
|
|
56
|
+
* @property {import("../semantic/types.js").Parameter[]} parameters - Semantic parameters.
|
|
57
|
+
* @property {import("../semantic/types.js").SemanticFunctionReturnType} returnType - Semantic return type.
|
|
58
|
+
* @property {import("../semantic/types.js").TypeParameter[]} [typeParameters] - Declaration-scoped parameters.
|
|
59
|
+
*/
|
|
32
60
|
/**
|
|
33
61
|
* Returns a normalized PHP node location.
|
|
34
62
|
* @param {import("php-parser").Node} node - PHP parser node.
|
|
@@ -100,15 +128,43 @@ function tokenLocation(tokenText, startOffset, endOffset, filename, source) {
|
|
|
100
128
|
* @param {import("php-parser").Expression} node - PHP expression.
|
|
101
129
|
* @param {string} filename - Source filename.
|
|
102
130
|
* @param {string} source - Complete source.
|
|
131
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
132
|
+
* @param {import("../semantic/types.js").SemanticValueType} [expectedType] - Contextual type for empty PHP arrays.
|
|
133
|
+
* @param {boolean} [preserveOptional] - Whether an optional identifier remains wrapped.
|
|
103
134
|
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
104
135
|
*/
|
|
105
|
-
function convertExpression(node, filename, source) {
|
|
136
|
+
function convertExpression(node, filename, source, context, expectedType, preserveOptional = false) {
|
|
106
137
|
const location = nodeLocation(node, filename, source);
|
|
138
|
+
if (expectedType?.kind == "OptionalType") {
|
|
139
|
+
if (node.kind == "nullkeyword") {
|
|
140
|
+
return withParserRanges({ kind: /** @type {const} */ ("OptionalNone"), location }, { absence: location });
|
|
141
|
+
}
|
|
142
|
+
if (knownExpressionType(node, context)?.kind == "OptionalType") {
|
|
143
|
+
return convertExpression(node, filename, source, context, undefined, true);
|
|
144
|
+
}
|
|
145
|
+
return withParserRanges({
|
|
146
|
+
kind: /** @type {const} */ ("OptionalSome"),
|
|
147
|
+
location,
|
|
148
|
+
value: convertExpression(node, filename, source, context, expectedType.valueType)
|
|
149
|
+
}, { some: location });
|
|
150
|
+
}
|
|
151
|
+
if (node.kind == "nullkeyword")
|
|
152
|
+
return unsupportedSyntax("php", "null outside an explicit optional context", location);
|
|
107
153
|
if (node.kind == "variable") {
|
|
108
154
|
const variable = /** @type {import("php-parser").Variable} */ (node);
|
|
109
155
|
if (typeof variable.name != "string")
|
|
110
156
|
return unsupportedSyntax("php", "dynamic variable", location);
|
|
111
|
-
|
|
157
|
+
if (variable.name == "this") {
|
|
158
|
+
if (!context.currentClass)
|
|
159
|
+
return unsupportedSyntax("php", "receiver outside a reference class", location);
|
|
160
|
+
return withParserRanges({ classId: /** @type {string} */ (context.currentClass.id),
|
|
161
|
+
kind: /** @type {const} */ ("ReceiverExpression"), location }, { receiver: location });
|
|
162
|
+
}
|
|
163
|
+
const identifier = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name: variable.name }, { name: location });
|
|
164
|
+
if (!preserveOptional && context.bindings.get(variable.name)?.kind == "OptionalType") {
|
|
165
|
+
return withParserRanges({ kind: /** @type {const} */ ("OptionalUnwrap"), location, operand: identifier }, { unwrap: location });
|
|
166
|
+
}
|
|
167
|
+
return identifier;
|
|
112
168
|
}
|
|
113
169
|
if (node.kind == "number") {
|
|
114
170
|
const literal = /** @type {import("php-parser").Number} */ (node);
|
|
@@ -144,6 +200,153 @@ function convertExpression(node, filename, source) {
|
|
|
144
200
|
}
|
|
145
201
|
if (node.kind == "nowdoc")
|
|
146
202
|
return unsupportedSyntax("php", "nowdoc string", location);
|
|
203
|
+
if (node.kind == "array") {
|
|
204
|
+
const literal = /** @type {import("php-parser").Array} */ (node);
|
|
205
|
+
const invalidEntry = literal.items.find((entry) => {
|
|
206
|
+
if (entry.kind != "entry")
|
|
207
|
+
return true;
|
|
208
|
+
const candidate = /** @type {import("php-parser").Entry} */ (entry);
|
|
209
|
+
return candidate.byRef || candidate.unpack;
|
|
210
|
+
});
|
|
211
|
+
if (invalidEntry)
|
|
212
|
+
return unsupportedSyntax("php", "array reference or unpacking", nodeLocation(invalidEntry, filename, source));
|
|
213
|
+
const entries = /** @type {import("php-parser").Entry[]} */ (literal.items);
|
|
214
|
+
const hasKeys = entries.some((entry) => entry.key != null);
|
|
215
|
+
const hasImplicit = entries.some((entry) => entry.key == null);
|
|
216
|
+
const collectionKind = entries.length == 0 ? expectedType?.kind : hasKeys && !hasImplicit
|
|
217
|
+
? expectedType?.kind == "OrderedMapType" ? "OrderedMapType" : "MapType"
|
|
218
|
+
: !hasKeys ? "ListType" : "mixed";
|
|
219
|
+
if (collectionKind == "mixed")
|
|
220
|
+
return unsupportedSyntax("php", "mixed list/map array literal", location);
|
|
221
|
+
if (collectionKind == "ListType") {
|
|
222
|
+
const elementType = expectedType?.kind == "ListType" ? expectedType.elementType : undefined;
|
|
223
|
+
return withParserRanges({
|
|
224
|
+
elements: entries.map((entry) => convertExpression(entry.value, filename, source, context, elementType)),
|
|
225
|
+
kind: /** @type {const} */ ("ListLiteral"),
|
|
226
|
+
location
|
|
227
|
+
}, { literal: location });
|
|
228
|
+
}
|
|
229
|
+
if (collectionKind == "MapType" || collectionKind == "OrderedMapType") {
|
|
230
|
+
const valueType = expectedType?.kind == "MapType" || expectedType?.kind == "OrderedMapType"
|
|
231
|
+
? expectedType.valueType : undefined;
|
|
232
|
+
const semanticEntries = entries.map((entry) => {
|
|
233
|
+
if (!entry.key || entry.key.kind != "string") {
|
|
234
|
+
return unsupportedSyntax("php", "map key other than a literal string", entry.key ? nodeLocation(entry.key, filename, source) : nodeLocation(entry, filename, source));
|
|
235
|
+
}
|
|
236
|
+
const key = convertExpression(entry.key, filename, source, context);
|
|
237
|
+
return withParserRanges({
|
|
238
|
+
key: /** @type {import("../semantic/types.js").StringLiteral} */ (key),
|
|
239
|
+
kind: /** @type {const} */ ("MapEntry"),
|
|
240
|
+
location: nodeLocation(entry, filename, source),
|
|
241
|
+
value: convertExpression(entry.value, filename, source, context, valueType)
|
|
242
|
+
}, { operator: tokenLocation("=>", entry.key.loc?.end.offset ?? 0, entry.value.loc?.start.offset ?? source.length, filename, source) });
|
|
243
|
+
});
|
|
244
|
+
return withParserRanges({
|
|
245
|
+
entries: semanticEntries,
|
|
246
|
+
kind: collectionKind == "OrderedMapType"
|
|
247
|
+
? /** @type {const} */ ("OrderedMapLiteral")
|
|
248
|
+
: /** @type {const} */ ("MapLiteral"),
|
|
249
|
+
location
|
|
250
|
+
}, { literal: location });
|
|
251
|
+
}
|
|
252
|
+
return unsupportedSyntax("php", "empty array without a list or map type", location);
|
|
253
|
+
}
|
|
254
|
+
if (node.kind == "new") {
|
|
255
|
+
const construction = /** @type {import("php-parser").New} */ (node);
|
|
256
|
+
const name = construction.what.kind == "name" ? /** @type {import("php-parser").Name} */ (construction.what) : undefined;
|
|
257
|
+
if (!name || name.resolution != "uqn" || typeof name.name != "string") {
|
|
258
|
+
return unsupportedSyntax("php", "dynamic or qualified record construction", nodeLocation(construction.what, filename, source));
|
|
259
|
+
}
|
|
260
|
+
const declaration = context.recordNames.get(name.name);
|
|
261
|
+
if (!declaration)
|
|
262
|
+
return unsupportedSyntax("php", "construction of an unknown nominal class", nodeLocation(construction.what, filename, source));
|
|
263
|
+
if (declaration.kind == "ClassDeclaration") {
|
|
264
|
+
const unsupportedArgument = construction.arguments.find((argument) => argument.kind == "namedargument" || argument.kind == "variadic" || Reflect.get(argument, "byref") === true);
|
|
265
|
+
if (unsupportedArgument)
|
|
266
|
+
return unsupportedSyntax("php", "non-positional reference constructor argument", nodeLocation(unsupportedArgument, filename, source));
|
|
267
|
+
const classLocation = nodeLocation(construction.what, filename, source);
|
|
268
|
+
return withParserRanges({ arguments: construction.arguments.map((argument, index) => convertExpression(argument, filename, source, context, declaration.constructor.parameters[index]?.type)),
|
|
269
|
+
kind: /** @type {const} */ ("ReferenceConstruction"), location,
|
|
270
|
+
reference: referenceType(/** @type {string} */ (declaration.id), classLocation) }, { class: classLocation });
|
|
271
|
+
}
|
|
272
|
+
if (declaration.kind == "EffectResourceDeclaration") {
|
|
273
|
+
return unsupportedSyntax("php", "owned resource construction", nodeLocation(construction, filename, source));
|
|
274
|
+
}
|
|
275
|
+
const contextualTypeArguments = expectedType?.kind == "RecordType" && expectedType.declarationId == declaration.id
|
|
276
|
+
? expectedType.arguments
|
|
277
|
+
: undefined;
|
|
278
|
+
const visibleTypeParameterIds = new Set([...context.typeParameters?.values() ?? []]
|
|
279
|
+
.map((parameter) => /** @type {string} */ (parameter.id)));
|
|
280
|
+
const typeArguments = contextualTypeArguments &&
|
|
281
|
+
!contextualTypeArguments.some((argument) => typeContainsAnyVariable(argument, visibleTypeParameterIds))
|
|
282
|
+
? contextualTypeArguments
|
|
283
|
+
: undefined;
|
|
284
|
+
return withParserRanges({
|
|
285
|
+
arguments: construction.arguments.map((argument, index) => convertExpression(argument, filename, source, context, instantiatedRecordFieldType(declaration, typeArguments, index))),
|
|
286
|
+
kind: /** @type {const} */ ("RecordConstruction"),
|
|
287
|
+
location,
|
|
288
|
+
record: recordType(/** @type {string} */ (declaration.id), nodeLocation(construction.what, filename, source), typeArguments)
|
|
289
|
+
}, { record: nodeLocation(construction.what, filename, source) });
|
|
290
|
+
}
|
|
291
|
+
if (node.kind == "propertylookup") {
|
|
292
|
+
const read = /** @type {import("php-parser").PropertyLookup} */ (node);
|
|
293
|
+
const offset = read.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (read.offset) : undefined;
|
|
294
|
+
if (!offset || typeof offset.name != "string") {
|
|
295
|
+
return unsupportedSyntax("php", "dynamic or computed member access", nodeLocation(read.offset, filename, source));
|
|
296
|
+
}
|
|
297
|
+
if (read.what.kind == "variable" && /** @type {import("php-parser").Variable} */ (read.what).name == "this" &&
|
|
298
|
+
context.currentClass) {
|
|
299
|
+
const field = context.currentClass.fields.find((candidate) => candidate.name == offset.name);
|
|
300
|
+
if (!field)
|
|
301
|
+
return unsupportedSyntax("php", `unknown private field '${offset.name}'`, nodeLocation(offset, filename, source));
|
|
302
|
+
return withParserRanges({ field: /** @type {string} */ (field.id), kind: /** @type {const} */ ("PrivateFieldRead"), location,
|
|
303
|
+
receiver: /** @type {import("../semantic/types.js").ReceiverExpression} */ (convertExpression(read.what, filename, source, context)) }, { member: nodeLocation(offset, filename, source) });
|
|
304
|
+
}
|
|
305
|
+
const receiverType = knownExpressionType(read.what, context);
|
|
306
|
+
if (receiverType?.kind == "ReferenceType") {
|
|
307
|
+
return unsupportedSyntax("php", "private reference-class field access", location);
|
|
308
|
+
}
|
|
309
|
+
const receiverRecord = receiverType?.kind == "OptionalType" ? receiverType.valueType : receiverType;
|
|
310
|
+
const declaration = receiverRecord?.kind == "RecordType" ? context.records.get(receiverRecord.declarationId) : undefined;
|
|
311
|
+
if ((declaration?.typeParameters?.length ?? 0) > 0) {
|
|
312
|
+
return unsupportedSyntax("php", "generic record property access", nodeLocation(read.offset, filename, source));
|
|
313
|
+
}
|
|
314
|
+
return withParserRanges({
|
|
315
|
+
field: offset.name,
|
|
316
|
+
kind: /** @type {const} */ ("MemberRead"),
|
|
317
|
+
location,
|
|
318
|
+
receiver: convertExpression(read.what, filename, source, context)
|
|
319
|
+
}, { member: nodeLocation(read.offset, filename, source) });
|
|
320
|
+
}
|
|
321
|
+
if (node.kind == "offsetlookup") {
|
|
322
|
+
const lookup = /** @type {import("php-parser").OffsetLookup} */ (node);
|
|
323
|
+
if (!lookup.offset)
|
|
324
|
+
return unsupportedSyntax("php", "append or missing array index", location);
|
|
325
|
+
const receiver = lookup.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
|
|
326
|
+
const receiverType = receiver && typeof receiver.name == "string" ? context.bindings.get(receiver.name) : undefined;
|
|
327
|
+
const accessKind = receiverType?.kind == "ListType" ? "list" :
|
|
328
|
+
receiverType?.kind == "MapType" || receiverType?.kind == "OrderedMapType" ? "map" :
|
|
329
|
+
lookup.offset.kind == "number" ? "list" : lookup.offset.kind == "string" ? "map" : undefined;
|
|
330
|
+
if (accessKind == "list" && ["number", "string", "variable"].includes(lookup.offset.kind)) {
|
|
331
|
+
return withParserRanges({
|
|
332
|
+
collection: convertExpression(lookup.what, filename, source, context),
|
|
333
|
+
index: convertExpression(lookup.offset, filename, source, context),
|
|
334
|
+
kind: /** @type {const} */ ("ListIndexExpression"),
|
|
335
|
+
location,
|
|
336
|
+
totality: /** @type {const} */ ("proven")
|
|
337
|
+
}, { operator: tokenLocation("[", lookup.what.loc?.end.offset ?? 0, lookup.offset.loc?.start.offset ?? source.length, filename, source) });
|
|
338
|
+
}
|
|
339
|
+
if (accessKind == "map" && ["number", "string", "variable"].includes(lookup.offset.kind)) {
|
|
340
|
+
return withParserRanges({
|
|
341
|
+
collection: convertExpression(lookup.what, filename, source, context),
|
|
342
|
+
key: convertExpression(lookup.offset, filename, source, context),
|
|
343
|
+
kind: /** @type {const} */ ("MapLookupExpression"),
|
|
344
|
+
location,
|
|
345
|
+
totality: /** @type {const} */ ("proven")
|
|
346
|
+
}, { operator: tokenLocation("[", lookup.what.loc?.end.offset ?? 0, lookup.offset.loc?.start.offset ?? source.length, filename, source) });
|
|
347
|
+
}
|
|
348
|
+
return unsupportedSyntax("php", "nonliteral array access", nodeLocation(lookup.offset, filename, source));
|
|
349
|
+
}
|
|
147
350
|
if (node.kind == "unary") {
|
|
148
351
|
const unary = /** @type {import("php-parser").Unary} */ (node);
|
|
149
352
|
if (!["!", "-"].includes(unary.type))
|
|
@@ -151,7 +354,7 @@ function convertExpression(node, filename, source) {
|
|
|
151
354
|
const semantic = withAdaptedOperation(withParserRanges({
|
|
152
355
|
kind: "UnaryExpression",
|
|
153
356
|
location,
|
|
154
|
-
operand: convertExpression(unary.what, filename, source)
|
|
357
|
+
operand: convertExpression(unary.what, filename, source, context)
|
|
155
358
|
}, {
|
|
156
359
|
operator: tokenLocation(unary.type, unary.loc?.start.offset ?? 0, unary.what.loc?.start.offset ?? unary.loc?.end.offset ?? source.length, filename, source)
|
|
157
360
|
}), unary.type == "!" ? "Not" : "Negate");
|
|
@@ -159,6 +362,12 @@ function convertExpression(node, filename, source) {
|
|
|
159
362
|
}
|
|
160
363
|
if (node.kind == "bin") {
|
|
161
364
|
const binary = /** @type {import("php-parser").Bin} */ (node);
|
|
365
|
+
if (binary.type == "!==" && binary.left.kind == "variable" && binary.right.kind == "nullkeyword") {
|
|
366
|
+
const operand = /** @type {import("../semantic/types.js").IdentifierExpression} */ (convertExpression(binary.left, filename, source, context, undefined, true));
|
|
367
|
+
return withParserRanges({ kind: /** @type {const} */ ("OptionalIsPresent"), location, operand }, {
|
|
368
|
+
operator: tokenLocation(binary.type, binary.left.loc?.end.offset ?? 0, binary.right.loc?.start.offset ?? source.length, filename, source)
|
|
369
|
+
});
|
|
370
|
+
}
|
|
162
371
|
if (["==", "!="].includes(binary.type))
|
|
163
372
|
return unsupportedSyntax("php", `coercive equality ${binary.type}`, location);
|
|
164
373
|
if (["and", "or"].includes(binary.type))
|
|
@@ -167,9 +376,9 @@ function convertExpression(node, filename, source) {
|
|
|
167
376
|
return unsupportedSyntax("php", `binary ${binary.type}`, location);
|
|
168
377
|
const semantic = withAdaptedOperation({
|
|
169
378
|
kind: /** @type {const} */ ("BinaryExpression"),
|
|
170
|
-
left: convertExpression(binary.left, filename, source),
|
|
379
|
+
left: convertExpression(binary.left, filename, source, context),
|
|
171
380
|
location,
|
|
172
|
-
right: convertExpression(binary.right, filename, source)
|
|
381
|
+
right: convertExpression(binary.right, filename, source, context)
|
|
173
382
|
}, /** @type {import("../semantic/operators.js").AdaptedOperation} */ (phpBinaryOperations.get(binary.type)));
|
|
174
383
|
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(withParserRanges(semantic, {
|
|
175
384
|
operator: tokenLocation(binary.type, binary.left.loc?.end.offset ?? 0, binary.right.loc?.start.offset ?? source.length, filename, source)
|
|
@@ -177,12 +386,69 @@ function convertExpression(node, filename, source) {
|
|
|
177
386
|
}
|
|
178
387
|
if (node.kind == "call") {
|
|
179
388
|
const call = /** @type {import("php-parser").Call} */ (node);
|
|
180
|
-
if (call.what.kind
|
|
389
|
+
if (call.what.kind == "propertylookup") {
|
|
390
|
+
const lookup = /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what));
|
|
391
|
+
const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
|
|
392
|
+
const receiverType = knownExpressionType(lookup.what, context);
|
|
393
|
+
if (member && typeof member.name == "string" && receiverType?.kind == "ReferenceType") {
|
|
394
|
+
const method = context.classes.get(receiverType.declarationId)?.methods.find((candidate) => candidate.name == member.name);
|
|
395
|
+
const unsupportedArgument = call.arguments.find((argument) => argument.kind == "namedargument" || argument.kind == "variadic" || Reflect.get(argument, "byref") === true);
|
|
396
|
+
if (unsupportedArgument)
|
|
397
|
+
return unsupportedSyntax("php", "non-positional method argument", nodeLocation(unsupportedArgument, filename, source));
|
|
398
|
+
return withParserRanges({ arguments: call.arguments.map((argument, index) => convertExpression(argument, filename, source, context, method?.parameters[index]?.type)),
|
|
399
|
+
kind: /** @type {const} */ ("MethodCallExpression"), location, method: method?.id ?? member.name,
|
|
400
|
+
receiver: convertExpression(lookup.what, filename, source, context) }, { member: nodeLocation(member, filename, source) });
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (call.what.kind == "propertylookup" && call.arguments.length == 0) {
|
|
404
|
+
const lookup = /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what));
|
|
405
|
+
const receiver = lookup.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
|
|
406
|
+
const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
|
|
407
|
+
if (receiver && typeof receiver.name == "string" && member?.name == "getMessage" && context.bindings.get(receiver.name)?.kind == "ErrorType") {
|
|
408
|
+
const receiverLocation = nodeLocation(receiver, filename, source);
|
|
409
|
+
return withParserRanges({
|
|
410
|
+
kind: /** @type {const} */ ("ErrorMessageRead"),
|
|
411
|
+
location,
|
|
412
|
+
receiver: withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: receiverLocation, name: receiver.name }, {
|
|
413
|
+
name: receiverLocation
|
|
414
|
+
})
|
|
415
|
+
}, { member: nodeLocation(member, filename, source) });
|
|
416
|
+
}
|
|
417
|
+
if (member && typeof member.name == "string" && knownGenericRecordAccessorType(lookup, context)) {
|
|
418
|
+
return withParserRanges({
|
|
419
|
+
field: member.name,
|
|
420
|
+
kind: /** @type {const} */ ("MemberRead"),
|
|
421
|
+
location,
|
|
422
|
+
receiver: convertExpression(lookup.what, filename, source, context)
|
|
423
|
+
}, { member: nodeLocation(member, filename, source) });
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
if (call.what.kind == "name" && call.what.name == "count" && call.arguments.length == 1) {
|
|
427
|
+
return withParserRanges({
|
|
428
|
+
collection: convertExpression(call.arguments[0], filename, source, context),
|
|
429
|
+
kind: /** @type {const} */ ("CollectionSizeExpression"),
|
|
430
|
+
location
|
|
431
|
+
}, { operator: nodeLocation(call.what, filename, source) });
|
|
432
|
+
}
|
|
433
|
+
if (call.what.kind != "name") {
|
|
181
434
|
return unsupportedSyntax("php", "dynamic call", location);
|
|
182
435
|
}
|
|
183
|
-
const
|
|
436
|
+
const calledName = /** @type {import("php-parser").Name} */ (call.what);
|
|
437
|
+
if (calledName.resolution != "uqn" || calledName.name.includes("\\")) {
|
|
438
|
+
return unsupportedSyntax("php", "qualified call", nodeLocation(call.what, filename, source));
|
|
439
|
+
}
|
|
440
|
+
const unsupportedArgument = call.arguments.find((argument) => argument.kind == "namedargument" || argument.kind == "variadic" || Reflect.get(argument, "byref") === true);
|
|
441
|
+
if (unsupportedArgument) {
|
|
442
|
+
const detail = unsupportedArgument.kind == "namedargument" ? "named argument" :
|
|
443
|
+
unsupportedArgument.kind == "variadic" ? "unpacked argument" : "by-reference argument";
|
|
444
|
+
return unsupportedSyntax("php", detail, nodeLocation(unsupportedArgument, filename, source));
|
|
445
|
+
}
|
|
446
|
+
const callee = calledName.name;
|
|
447
|
+
const signature = context.functions.get(callee);
|
|
448
|
+
const knownArguments = call.arguments.map((argument) => knownCallArgumentType(argument, context));
|
|
449
|
+
const parameterTypes = signature ? knownCallParameterTypes(signature, knownArguments) : undefined;
|
|
184
450
|
return withParserRanges({
|
|
185
|
-
arguments: call.arguments.map((argument) => convertExpression(argument, filename, source)),
|
|
451
|
+
arguments: call.arguments.map((argument, index) => convertExpression(argument, filename, source, context, parameterTypes?.[index] ?? signature?.parameters[index]?.type, preservesGenericOptionalEvidence(signature, index))),
|
|
186
452
|
callee,
|
|
187
453
|
kind: "CallExpression",
|
|
188
454
|
location
|
|
@@ -190,21 +456,144 @@ function convertExpression(node, filename, source) {
|
|
|
190
456
|
}
|
|
191
457
|
return unsupportedSyntax("php", node.kind, location);
|
|
192
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* Resolves only result types established by explicit signatures and bindings.
|
|
461
|
+
* @param {import("php-parser").Expression} node - Parser-owned expression.
|
|
462
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
463
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType | import("../semantic/types.js").ErrorType | undefined} Known result type.
|
|
464
|
+
*/
|
|
465
|
+
function knownExpressionType(node, context) {
|
|
466
|
+
if (node.kind == "variable") {
|
|
467
|
+
const variable = /** @type {import("php-parser").Variable} */ (node);
|
|
468
|
+
if (variable.name == "this" && context.currentClass?.id) {
|
|
469
|
+
return { declarationId: context.currentClass.id, kind: "ReferenceType" };
|
|
470
|
+
}
|
|
471
|
+
if (typeof variable.name == "string")
|
|
472
|
+
return context.bindings.get(variable.name);
|
|
473
|
+
}
|
|
474
|
+
if (node.kind == "call") {
|
|
475
|
+
const call = /** @type {import("php-parser").Call} */ (node);
|
|
476
|
+
const name = call.what.kind == "name" && typeof call.what.name == "string" ? call.what.name : undefined;
|
|
477
|
+
if (name) {
|
|
478
|
+
const signature = context.functions.get(name);
|
|
479
|
+
if (signature)
|
|
480
|
+
return knownCallReturnType(signature, call.arguments.map((argument) => knownExpressionType(argument, context)));
|
|
481
|
+
}
|
|
482
|
+
if (call.what.kind == "propertylookup" && call.arguments.length == 0) {
|
|
483
|
+
return knownGenericRecordAccessorType(
|
|
484
|
+
/** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what)), context);
|
|
485
|
+
}
|
|
486
|
+
if (call.what.kind == "propertylookup") {
|
|
487
|
+
const lookup = /** @type {import("php-parser").PropertyLookup} */ ( /** @type {unknown} */(call.what));
|
|
488
|
+
const receiver = knownExpressionType(lookup.what, context);
|
|
489
|
+
const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
|
|
490
|
+
if (receiver?.kind == "ReferenceType" && member && typeof member.name == "string") {
|
|
491
|
+
return context.classes.get(receiver.declarationId)?.methods.find((method) => method.name == member.name)?.returnType;
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
if (node.kind == "offsetlookup") {
|
|
496
|
+
const lookup = /** @type {import("php-parser").OffsetLookup} */ (node);
|
|
497
|
+
const collectionType = knownExpressionType(lookup.what, context);
|
|
498
|
+
if (collectionType?.kind == "ListType")
|
|
499
|
+
return collectionType.elementType;
|
|
500
|
+
if (collectionType?.kind == "MapType" || collectionType?.kind == "OrderedMapType")
|
|
501
|
+
return collectionType.valueType;
|
|
502
|
+
}
|
|
503
|
+
if (node.kind == "new") {
|
|
504
|
+
const construction = /** @type {import("php-parser").New} */ (node);
|
|
505
|
+
const name = construction.what.kind == "name" ? /** @type {import("php-parser").Name} */ (construction.what) : undefined;
|
|
506
|
+
const declaration = name && typeof name.name == "string" ? context.recordNames.get(name.name) : undefined;
|
|
507
|
+
if (declaration?.id)
|
|
508
|
+
return declaration.kind == "ClassDeclaration"
|
|
509
|
+
? { declarationId: declaration.id, kind: "ReferenceType" }
|
|
510
|
+
: { declarationId: declaration.id, kind: "RecordType" };
|
|
511
|
+
}
|
|
512
|
+
if (node.kind == "propertylookup") {
|
|
513
|
+
const read = /** @type {import("php-parser").PropertyLookup} */ (node);
|
|
514
|
+
const receiver = knownExpressionType(read.what, context);
|
|
515
|
+
if (read.what.kind == "variable" && /** @type {import("php-parser").Variable} */ (read.what).name == "this" &&
|
|
516
|
+
context.currentClass) {
|
|
517
|
+
const offset = read.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (read.offset) : undefined;
|
|
518
|
+
return context.currentClass.fields.find((field) => field.name == offset?.name)?.type;
|
|
519
|
+
}
|
|
520
|
+
if (receiver?.kind != "RecordType")
|
|
521
|
+
return undefined;
|
|
522
|
+
const declaration = context.records.get(receiver.declarationId);
|
|
523
|
+
const offset = read.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (read.offset) : undefined;
|
|
524
|
+
const memberName = offset && typeof offset.name == "string" ? offset.name : undefined;
|
|
525
|
+
if (memberName && declaration) {
|
|
526
|
+
const index = declaration.fields.findIndex((field) => field.name == memberName);
|
|
527
|
+
return instantiatedRecordFieldType(declaration, receiver.arguments, index);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return undefined;
|
|
531
|
+
}
|
|
532
|
+
/**
|
|
533
|
+
* Resolves exact parser-known argument evidence without changing the established
|
|
534
|
+
* expression-result classifier used for optional conversion.
|
|
535
|
+
* @param {import("php-parser").Expression} node - Parser-owned call argument.
|
|
536
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
537
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType | import("../semantic/types.js").ErrorType | undefined} Known argument type.
|
|
538
|
+
*/
|
|
539
|
+
function knownCallArgumentType(node, context) {
|
|
540
|
+
const known = knownExpressionType(node, context);
|
|
541
|
+
if (known)
|
|
542
|
+
return known;
|
|
543
|
+
if (node.kind == "number" && Number.isSafeInteger(Number(/** @type {import("php-parser").Number} */ (node).value))) {
|
|
544
|
+
return scalarType("integer");
|
|
545
|
+
}
|
|
546
|
+
if (node.kind == "boolean" && typeof /** @type {import("php-parser").Boolean} */ (node).value == "boolean") {
|
|
547
|
+
return scalarType("boolean");
|
|
548
|
+
}
|
|
549
|
+
if (node.kind == "string" && typeof /** @type {import("php-parser").String} */ (node).value == "string" &&
|
|
550
|
+
hasOnlyUnicodeScalars(/** @type {import("php-parser").String} */ (node).value)) {
|
|
551
|
+
return scalarType("string");
|
|
552
|
+
}
|
|
553
|
+
return undefined;
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* Resolves PHP's exact zero-argument accessor carrier against its receiver's
|
|
557
|
+
* generic record declaration.
|
|
558
|
+
* @param {import("php-parser").PropertyLookup} lookup - Parser-owned method lookup.
|
|
559
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
560
|
+
* @returns {import("../semantic/types.js").SemanticValueType | undefined} Instantiated field type.
|
|
561
|
+
*/
|
|
562
|
+
function knownGenericRecordAccessorType(lookup, context) {
|
|
563
|
+
const receiver = knownExpressionType(lookup.what, context);
|
|
564
|
+
const receiverRecord = receiver?.kind == "OptionalType" ? receiver.valueType : receiver;
|
|
565
|
+
if (receiverRecord?.kind != "RecordType")
|
|
566
|
+
return undefined;
|
|
567
|
+
const declaration = context.records.get(receiverRecord.declarationId);
|
|
568
|
+
const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
|
|
569
|
+
const index = member && typeof member.name == "string"
|
|
570
|
+
? declaration?.fields.findIndex((field) => field.name == member.name) ?? -1
|
|
571
|
+
: -1;
|
|
572
|
+
if (!declaration || (declaration.typeParameters?.length ?? 0) == 0 || index < 0)
|
|
573
|
+
return undefined;
|
|
574
|
+
return instantiatedRecordFieldType(declaration, receiverRecord.arguments, index);
|
|
575
|
+
}
|
|
193
576
|
/**
|
|
194
577
|
* Converts one explicit PHP return.
|
|
195
578
|
* @param {import("php-parser").Node} node - PHP node.
|
|
196
579
|
* @param {string} filename - Source filename.
|
|
197
580
|
* @param {string} source - Complete source.
|
|
581
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
198
582
|
* @returns {import("../semantic/types.js").ReturnStatement} Semantic return.
|
|
199
583
|
*/
|
|
200
|
-
function convertReturn(node, filename, source) {
|
|
584
|
+
function convertReturn(node, filename, source, context) {
|
|
201
585
|
const location = nodeLocation(node, filename, source);
|
|
202
586
|
if (node.kind != "return")
|
|
203
587
|
return unsupportedSyntax("php", node.kind, location);
|
|
204
588
|
const returnNode = /** @type {import("php-parser").Return} */ (node);
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
589
|
+
const expectedType = context.returnType?.kind == "TypeReference" && context.returnType.name == "void"
|
|
590
|
+
? undefined
|
|
591
|
+
: /** @type {import("../semantic/types.js").SemanticValueType | undefined} */ (context.returnType);
|
|
592
|
+
return {
|
|
593
|
+
...(returnNode.expr ? { expression: convertExpression(returnNode.expr, filename, source, context, expectedType) } : {}),
|
|
594
|
+
kind: "ReturnStatement",
|
|
595
|
+
location
|
|
596
|
+
};
|
|
208
597
|
}
|
|
209
598
|
/**
|
|
210
599
|
* Reads one exact PHP local `@var` carrier and immutability marker.
|
|
@@ -212,9 +601,11 @@ function convertReturn(node, filename, source) {
|
|
|
212
601
|
* @param {string} name - Local name.
|
|
213
602
|
* @param {string} filename - Source filename.
|
|
214
603
|
* @param {string} source - Complete source.
|
|
215
|
-
* @
|
|
604
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
|
|
605
|
+
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
606
|
+
* @returns {{immutable: boolean, type: import("../semantic/types.js").SemanticValueType} | undefined} Metadata when present.
|
|
216
607
|
*/
|
|
217
|
-
function localMetadata(node, name, filename, source) {
|
|
608
|
+
function localMetadata(node, name, filename, source, recordNames, typeParameters = new Map()) {
|
|
218
609
|
const comments = node.leadingComments ?? [];
|
|
219
610
|
const comment = comments.at(-1);
|
|
220
611
|
if (!comment || comment.kind != "commentblock" || !comment.loc || !node.loc)
|
|
@@ -237,18 +628,27 @@ function localMetadata(node, name, filename, source) {
|
|
|
237
628
|
}
|
|
238
629
|
return {
|
|
239
630
|
immutable: immutable.length == 1,
|
|
240
|
-
type:
|
|
631
|
+
type: documentedValueType({
|
|
632
|
+
language: "php",
|
|
633
|
+
location: commentTagLocation(comment, variables[0], "name", filename, source),
|
|
634
|
+
ownerLocation: location,
|
|
635
|
+
records: recordNames,
|
|
636
|
+
source,
|
|
637
|
+
sourceType: variables[0].name,
|
|
638
|
+
subject: `Local '${name}'`,
|
|
639
|
+
typeParameters
|
|
640
|
+
})
|
|
241
641
|
};
|
|
242
642
|
}
|
|
243
643
|
/**
|
|
244
644
|
* Converts one PHP local declaration or assignment.
|
|
245
645
|
* @param {import("php-parser").Node} node - PHP statement.
|
|
246
|
-
* @param {Set<string>} visible - Names visible during adaptation.
|
|
247
646
|
* @param {string} filename - Source filename.
|
|
248
647
|
* @param {string} source - Complete source.
|
|
249
|
-
* @
|
|
648
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
649
|
+
* @returns {import("../semantic/types.js").LocalStatement | import("../semantic/types.js").PrivateFieldWriteStatement} Semantic local or private-field statement.
|
|
250
650
|
*/
|
|
251
|
-
function convertLocalStatement(node,
|
|
651
|
+
function convertLocalStatement(node, filename, source, context) {
|
|
252
652
|
const location = nodeLocation(node, filename, source);
|
|
253
653
|
if (node.kind != "expressionstatement")
|
|
254
654
|
return unsupportedSyntax("php", node.kind, location);
|
|
@@ -258,34 +658,76 @@ function convertLocalStatement(node, visible, filename, source) {
|
|
|
258
658
|
const assignment = /** @type {import("php-parser").Assign} */ (expression);
|
|
259
659
|
if (assignment.operator != "=")
|
|
260
660
|
return unsupportedSyntax("php", `assignment ${assignment.operator}`, location);
|
|
661
|
+
if (assignment.left.kind == "propertylookup" && context.currentClass) {
|
|
662
|
+
const lookup = /** @type {import("php-parser").PropertyLookup} */ (assignment.left);
|
|
663
|
+
const receiver = lookup.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
|
|
664
|
+
const member = lookup.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
|
|
665
|
+
const field = receiver?.name == "this" && member && typeof member.name == "string"
|
|
666
|
+
? context.currentClass.fields.find((candidate) => candidate.name == member.name)
|
|
667
|
+
: undefined;
|
|
668
|
+
if (!field)
|
|
669
|
+
return unsupportedSyntax("php", "private field write outside the declaring receiver", nodeLocation(assignment.left, filename, source));
|
|
670
|
+
return withParserRanges({ expression: convertExpression(assignment.right, filename, source, context, field.type),
|
|
671
|
+
field: /** @type {string} */ (field.id), kind: /** @type {const} */ ("PrivateFieldWriteStatement"), location,
|
|
672
|
+
receiver: /** @type {import("../semantic/types.js").ReceiverExpression} */ (convertExpression(lookup.what, filename, source, context)) }, { member: nodeLocation(/** @type {import("php-parser").Identifier} */ (member), filename, source), operator: tokenLocation("=", assignment.left.loc?.end.offset ?? 0, assignment.right.loc?.start.offset ?? source.length, filename, source) });
|
|
673
|
+
}
|
|
261
674
|
if (assignment.left.kind != "variable")
|
|
262
675
|
return unsupportedSyntax("php", assignment.left.kind, nodeLocation(assignment.left, filename, source));
|
|
676
|
+
if (assignment.right.kind == "throw") {
|
|
677
|
+
return unsupportedSyntax("php", "throw expression in a value context", nodeLocation(assignment.right, filename, source));
|
|
678
|
+
}
|
|
263
679
|
const variable = /** @type {import("php-parser").Variable} */ (assignment.left);
|
|
264
680
|
const targetLocation = nodeLocation(variable, filename, source);
|
|
265
681
|
if (typeof variable.name != "string" || variable.curly)
|
|
266
682
|
return unsupportedSyntax("php", "dynamic variable", targetLocation);
|
|
267
|
-
const metadata = localMetadata(node, variable.name, filename, source);
|
|
683
|
+
const metadata = localMetadata(node, variable.name, filename, source, context.recordNames, context.typeParameters);
|
|
268
684
|
if (metadata) {
|
|
269
|
-
|
|
685
|
+
let declaredType = metadata.type;
|
|
686
|
+
let ordered = false;
|
|
687
|
+
if (declaredType.kind == "MapType" && context.orderedMapDeclarations?.has(assignment) && assignment.right.kind == "array") {
|
|
688
|
+
declaredType = orderedMapTypeFromMap(declaredType, location);
|
|
689
|
+
ordered = true;
|
|
690
|
+
}
|
|
691
|
+
const initializer = convertExpression(assignment.right, filename, source, context, declaredType);
|
|
692
|
+
context.bindings.set(variable.name, declaredType);
|
|
270
693
|
return withParserRanges({
|
|
271
|
-
initializer
|
|
694
|
+
initializer,
|
|
272
695
|
kind: "LocalDeclaration",
|
|
273
696
|
location,
|
|
274
|
-
mutable: !metadata.immutable,
|
|
697
|
+
mutable: ordered ? false : !metadata.immutable,
|
|
698
|
+
name: variable.name,
|
|
699
|
+
type: declaredType
|
|
700
|
+
}, {
|
|
701
|
+
name: targetLocation,
|
|
702
|
+
operator: tokenLocation("=", assignment.left.loc?.end.offset ?? 0, assignment.right.loc?.start.offset ?? source.length, filename, source)
|
|
703
|
+
});
|
|
704
|
+
}
|
|
705
|
+
const inferredType = knownExpressionType(assignment.right, context);
|
|
706
|
+
if (inferredType?.kind == "RecordType" || inferredType?.kind == "ReferenceType" ||
|
|
707
|
+
inferredType?.kind == "OwnedResourceType") {
|
|
708
|
+
const initializer = convertExpression(assignment.right, filename, source, context, inferredType);
|
|
709
|
+
context.bindings.set(variable.name, inferredType);
|
|
710
|
+
return withParserRanges({
|
|
711
|
+
initializer,
|
|
712
|
+
kind: /** @type {const} */ ("LocalDeclaration"),
|
|
713
|
+
location,
|
|
714
|
+
mutable: false,
|
|
275
715
|
name: variable.name,
|
|
276
|
-
type:
|
|
716
|
+
type: inferredType
|
|
277
717
|
}, {
|
|
278
718
|
name: targetLocation,
|
|
279
719
|
operator: tokenLocation("=", assignment.left.loc?.end.offset ?? 0, assignment.right.loc?.start.offset ?? source.length, filename, source)
|
|
280
720
|
});
|
|
281
721
|
}
|
|
282
|
-
|
|
722
|
+
const bindingType = context.bindings.get(variable.name);
|
|
723
|
+
if (!bindingType)
|
|
283
724
|
return missingType("php", `Local '${variable.name}'`, location);
|
|
284
725
|
const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: targetLocation, name: variable.name }, {
|
|
285
726
|
name: targetLocation
|
|
286
727
|
});
|
|
728
|
+
const value = convertExpression(assignment.right, filename, source, context, bindingType.kind == "ErrorType" ? undefined : bindingType);
|
|
287
729
|
return withParserRanges({
|
|
288
|
-
expression:
|
|
730
|
+
expression: value,
|
|
289
731
|
kind: "AssignmentStatement",
|
|
290
732
|
location,
|
|
291
733
|
target
|
|
@@ -296,35 +738,225 @@ function convertLocalStatement(node, visible, filename, source) {
|
|
|
296
738
|
/**
|
|
297
739
|
* Converts one exhaustive PHP statement.
|
|
298
740
|
* @param {import("php-parser").Node} node - PHP statement.
|
|
299
|
-
* @param {Set<string>} visible - Names visible during adaptation.
|
|
300
741
|
* @param {string} filename - Source filename.
|
|
301
742
|
* @param {string} source - Complete source.
|
|
743
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
302
744
|
* @returns {import("../semantic/types.js").Statement} Semantic statement.
|
|
303
745
|
*/
|
|
304
|
-
function convertStatement(node,
|
|
746
|
+
function convertStatement(node, filename, source, context) {
|
|
305
747
|
if (node.kind == "return")
|
|
306
|
-
return convertReturn(node, filename, source);
|
|
748
|
+
return convertReturn(node, filename, source, context);
|
|
307
749
|
if (node.kind == "if")
|
|
308
|
-
return convertIf(/** @type {import("php-parser").If} */ (node),
|
|
750
|
+
return convertIf(/** @type {import("php-parser").If} */ (node), filename, source, context);
|
|
751
|
+
if (node.kind == "throw")
|
|
752
|
+
return convertPhpRaise(node, filename, source, context);
|
|
753
|
+
if (node.kind == "try")
|
|
754
|
+
return convertPhpTry(node, filename, source, context);
|
|
755
|
+
if (node.kind == "while")
|
|
756
|
+
return convertWhile(/** @type {import("php-parser").While} */ (node), filename, source, context);
|
|
757
|
+
if (node.kind == "foreach")
|
|
758
|
+
return convertForEach(/** @type {import("php-parser").Foreach} */ (node), filename, source, context);
|
|
759
|
+
if (node.kind == "break" || node.kind == "continue") {
|
|
760
|
+
const control = /** @type {import("php-parser").Break | import("php-parser").Continue} */ (node);
|
|
761
|
+
if (control.level)
|
|
762
|
+
return unsupportedSyntax("php", `${node.kind} level`, nodeLocation(node, filename, source));
|
|
763
|
+
const location = tokenLocation(node.kind, node.loc?.start.offset ?? 0, node.loc?.end.offset ?? source.length, filename, source);
|
|
764
|
+
return withParserRanges({
|
|
765
|
+
kind: /** @type {"BreakStatement" | "ContinueStatement"} */ (node.kind == "break" ? "BreakStatement" : "ContinueStatement"),
|
|
766
|
+
location
|
|
767
|
+
}, { keyword: location });
|
|
768
|
+
}
|
|
309
769
|
if (node.kind == "echo")
|
|
310
|
-
return convertPrint(/** @type {import("php-parser").Echo} */ (node), filename, source);
|
|
311
|
-
if (node.kind == "expressionstatement")
|
|
312
|
-
|
|
770
|
+
return convertPrint(/** @type {import("php-parser").Echo} */ (node), filename, source, context);
|
|
771
|
+
if (node.kind == "expressionstatement") {
|
|
772
|
+
const expression = /** @type {import("php-parser").ExpressionStatement} */ (node).expression;
|
|
773
|
+
if (expression.kind == "call") {
|
|
774
|
+
return {
|
|
775
|
+
expression: /** @type {import("../semantic/types.js").CallExpression | import("../semantic/types.js").MethodCallExpression} */ (convertExpression(expression, filename, source, context)),
|
|
776
|
+
kind: "ExpressionStatement",
|
|
777
|
+
location: nodeLocation(node, filename, source)
|
|
778
|
+
};
|
|
779
|
+
}
|
|
780
|
+
return convertLocalStatement(node, filename, source, context);
|
|
781
|
+
}
|
|
313
782
|
return unsupportedSyntax("php", node.kind, nodeLocation(node, filename, source));
|
|
314
783
|
}
|
|
784
|
+
/**
|
|
785
|
+
* Converts exact `throw new DeclaredError(message)`.
|
|
786
|
+
* @param {import("php-parser").Node} node - PHP throw node.
|
|
787
|
+
* @param {string} filename - Source filename.
|
|
788
|
+
* @param {string} source - Complete source.
|
|
789
|
+
* @param {PhpConversionContext} context - Typed lexical context.
|
|
790
|
+
* @returns {import("../semantic/types.js").RaiseStatement} Semantic raise.
|
|
791
|
+
*/
|
|
792
|
+
function convertPhpRaise(node, filename, source, context) {
|
|
793
|
+
const location = nodeLocation(node, filename, source);
|
|
794
|
+
const construction = Reflect.get(node, "what");
|
|
795
|
+
if (!construction || construction.kind != "new" || construction.what?.kind != "name" ||
|
|
796
|
+
construction.what.resolution != "uqn" || !context.errorNames.has(construction.what.name) ||
|
|
797
|
+
!Array.isArray(construction.arguments) || construction.arguments.length != 1 ||
|
|
798
|
+
construction.arguments[0].kind == "namedargument" || construction.arguments[0].kind == "variadic") {
|
|
799
|
+
return unsupportedSyntax("php", "throw other than exact declared error construction", location);
|
|
800
|
+
}
|
|
801
|
+
const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(construction.what.name));
|
|
802
|
+
const typeLocation = nodeLocation(construction.what, filename, source);
|
|
803
|
+
return withParserRanges({
|
|
804
|
+
error: withParserRanges({
|
|
805
|
+
error: withParserRanges({ declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType") }, { type: typeLocation }),
|
|
806
|
+
kind: /** @type {const} */ ("ErrorConstruction"),
|
|
807
|
+
location: nodeLocation(construction, filename, source),
|
|
808
|
+
message: convertExpression(construction.arguments[0], filename, source, context)
|
|
809
|
+
}, { type: typeLocation }),
|
|
810
|
+
kind: /** @type {const} */ ("RaiseStatement"),
|
|
811
|
+
location
|
|
812
|
+
}, { keyword: tokenLocation("throw", node.loc?.start.offset ?? 0, construction.loc?.start.offset ?? source.length, filename, source) });
|
|
813
|
+
}
|
|
814
|
+
/**
|
|
815
|
+
* Converts one exact typed catch with no finally.
|
|
816
|
+
* @param {import("php-parser").Node} node - PHP try node.
|
|
817
|
+
* @param {string} filename - Source filename.
|
|
818
|
+
* @param {string} source - Complete source.
|
|
819
|
+
* @param {PhpConversionContext} context - Typed lexical context.
|
|
820
|
+
* @returns {import("../semantic/types.js").TryStatement} Semantic exact handler.
|
|
821
|
+
*/
|
|
822
|
+
function convertPhpTry(node, filename, source, context) {
|
|
823
|
+
const location = nodeLocation(node, filename, source);
|
|
824
|
+
const catches = Reflect.get(node, "catches");
|
|
825
|
+
const body = Reflect.get(node, "body");
|
|
826
|
+
if (Reflect.get(node, "always") || !Array.isArray(catches) || catches.length != 1 || body?.kind != "block") {
|
|
827
|
+
return unsupportedSyntax("php", "try without one typed catch and no finally", location);
|
|
828
|
+
}
|
|
829
|
+
const handler = catches[0];
|
|
830
|
+
const caught = handler.what?.[0];
|
|
831
|
+
const binding = handler.variable;
|
|
832
|
+
if (handler.what?.length != 1 || caught?.kind != "name" || caught.resolution != "uqn" ||
|
|
833
|
+
!context.errorNames.has(caught.name) || binding?.kind != "variable" || typeof binding.name != "string" ||
|
|
834
|
+
binding.curly || handler.body?.kind != "block") {
|
|
835
|
+
return unsupportedSyntax("php", "broad, multiple, or malformed catch", nodeLocation(handler, filename, source));
|
|
836
|
+
}
|
|
837
|
+
const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(caught.name));
|
|
838
|
+
const caughtLocation = nodeLocation(caught, filename, source);
|
|
839
|
+
const catchType = withParserRanges({ declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType") }, {
|
|
840
|
+
type: caughtLocation
|
|
841
|
+
});
|
|
842
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
843
|
+
const catchContext = { ...context, bindings: new Map(context.bindings) };
|
|
844
|
+
catchContext.bindings.set(binding.name, catchType);
|
|
845
|
+
return withParserRanges({
|
|
846
|
+
body: convertBlock(body, filename, source, bodyContext),
|
|
847
|
+
catchBinding: withParserRanges({
|
|
848
|
+
kind: /** @type {const} */ ("CatchBinding"),
|
|
849
|
+
location: nodeLocation(binding, filename, source),
|
|
850
|
+
mutable: /** @type {const} */ (false),
|
|
851
|
+
name: binding.name,
|
|
852
|
+
type: catchType
|
|
853
|
+
}, { name: nodeLocation(binding, filename, source) }),
|
|
854
|
+
catchBody: convertBlock(handler.body, filename, source, catchContext),
|
|
855
|
+
catchType,
|
|
856
|
+
kind: /** @type {const} */ ("TryStatement"),
|
|
857
|
+
location
|
|
858
|
+
}, { catch: nodeLocation(handler, filename, source), try: tokenLocation("try", node.loc?.start.offset ?? 0, body.loc?.start.offset ?? source.length, filename, source) });
|
|
859
|
+
}
|
|
860
|
+
/**
|
|
861
|
+
* Converts exact block-form PHP `foreach ($list as $value)`.
|
|
862
|
+
* @param {import("php-parser").Foreach} node - PHP foreach node.
|
|
863
|
+
* @param {string} filename - Source filename.
|
|
864
|
+
* @param {string} source - Complete source.
|
|
865
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
866
|
+
* @returns {import("../semantic/types.js").ForEachStatement | import("../semantic/types.js").ForEachMapStatement} Semantic loop.
|
|
867
|
+
*/
|
|
868
|
+
function convertForEach(node, filename, source, context) {
|
|
869
|
+
const location = nodeLocation(node, filename, source);
|
|
870
|
+
if (node.shortForm)
|
|
871
|
+
return unsupportedSyntax("php", "alternative foreach syntax", location);
|
|
872
|
+
if (node.value.kind != "variable")
|
|
873
|
+
return unsupportedSyntax("php", "foreach destructuring", nodeLocation(node.value, filename, source));
|
|
874
|
+
const variable = /** @type {import("php-parser").Variable} */ (node.value);
|
|
875
|
+
if (Reflect.get(variable, "byref") === true)
|
|
876
|
+
return unsupportedSyntax("php", "by-reference foreach", nodeLocation(variable, filename, source));
|
|
877
|
+
if (typeof variable.name != "string" || variable.curly)
|
|
878
|
+
return unsupportedSyntax("php", "dynamic foreach binding", nodeLocation(variable, filename, source));
|
|
879
|
+
if (!node.body || node.body.kind != "block") {
|
|
880
|
+
return unsupportedSyntax("php", "foreach without block body", node.body ? nodeLocation(node.body, filename, source) : location);
|
|
881
|
+
}
|
|
882
|
+
const body = /** @type {import("php-parser").Block} */ (node.body);
|
|
883
|
+
const collectionType = iterationOperandType(knownExpressionType(node.source, context));
|
|
884
|
+
if (node.key) {
|
|
885
|
+
if (node.key.kind != "variable")
|
|
886
|
+
return unsupportedSyntax("php", "foreach key binding shape", nodeLocation(node.key, filename, source));
|
|
887
|
+
const keyVariable = /** @type {import("php-parser").Variable} */ (node.key);
|
|
888
|
+
if (Reflect.get(keyVariable, "byref") === true || typeof keyVariable.name != "string" || keyVariable.curly) {
|
|
889
|
+
return unsupportedSyntax("php", "invalid foreach key binding", nodeLocation(keyVariable, filename, source));
|
|
890
|
+
}
|
|
891
|
+
if (collectionType?.kind == "MapType") {
|
|
892
|
+
return unsupportedSyntax("php", "unordered map iteration", nodeLocation(node.source, filename, source));
|
|
893
|
+
}
|
|
894
|
+
if (!collectionType || collectionType.kind != "OrderedMapType") {
|
|
895
|
+
return missingType("php", "Ordered map iteration collection", nodeLocation(node.source, filename, source));
|
|
896
|
+
}
|
|
897
|
+
const keyLocation = nodeLocation(keyVariable, filename, source);
|
|
898
|
+
const valueLocation = nodeLocation(variable, filename, source);
|
|
899
|
+
const keyType = iterationBindingType(collectionType.keyType, keyLocation);
|
|
900
|
+
const valueType = iterationBindingType(collectionType.valueType, valueLocation);
|
|
901
|
+
const keyBinding = withParserRanges({
|
|
902
|
+
kind: /** @type {const} */ ("ValueBinding"), location: keyLocation, mutable: /** @type {const} */ (false),
|
|
903
|
+
name: keyVariable.name, type: keyType
|
|
904
|
+
}, { name: keyLocation });
|
|
905
|
+
const valueBinding = withParserRanges({
|
|
906
|
+
kind: /** @type {const} */ ("ValueBinding"), location: valueLocation, mutable: /** @type {const} */ (false),
|
|
907
|
+
name: variable.name, type: valueType
|
|
908
|
+
}, { name: valueLocation });
|
|
909
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
910
|
+
bodyContext.bindings.set(keyVariable.name, keyType);
|
|
911
|
+
bodyContext.bindings.set(variable.name, valueType);
|
|
912
|
+
return withParserRanges({
|
|
913
|
+
body: convertBlock(body, filename, source, bodyContext),
|
|
914
|
+
keyBinding,
|
|
915
|
+
kind: /** @type {const} */ ("ForEachMapStatement"),
|
|
916
|
+
location,
|
|
917
|
+
map: convertExpression(node.source, filename, source, context),
|
|
918
|
+
valueBinding
|
|
919
|
+
}, { operator: tokenLocation("foreach", node.loc?.start.offset ?? 0, node.source.loc?.start.offset ?? source.length, filename, source) });
|
|
920
|
+
}
|
|
921
|
+
if (collectionType?.kind == "MapType" || collectionType?.kind == "OrderedMapType") {
|
|
922
|
+
return unsupportedSyntax("php", "map iteration without key/value pair binding", nodeLocation(node.source, filename, source));
|
|
923
|
+
}
|
|
924
|
+
if (!collectionType || collectionType.kind != "ListType") {
|
|
925
|
+
return missingType("php", "Iteration collection", nodeLocation(node.source, filename, source));
|
|
926
|
+
}
|
|
927
|
+
const bindingLocation = nodeLocation(variable, filename, source);
|
|
928
|
+
const inferredType = collectionType.elementType;
|
|
929
|
+
const bindingType = iterationBindingType(inferredType, bindingLocation);
|
|
930
|
+
const valueBinding = withParserRanges({
|
|
931
|
+
kind: /** @type {const} */ ("ValueBinding"),
|
|
932
|
+
location: bindingLocation,
|
|
933
|
+
mutable: /** @type {const} */ (false),
|
|
934
|
+
name: variable.name,
|
|
935
|
+
type: bindingType
|
|
936
|
+
}, { name: bindingLocation });
|
|
937
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
938
|
+
bodyContext.bindings.set(variable.name, bindingType);
|
|
939
|
+
return withParserRanges({
|
|
940
|
+
body: convertBlock(body, filename, source, bodyContext),
|
|
941
|
+
kind: /** @type {const} */ ("ForEachStatement"),
|
|
942
|
+
list: convertExpression(node.source, filename, source, context),
|
|
943
|
+
location,
|
|
944
|
+
valueBinding
|
|
945
|
+
}, { operator: tokenLocation("foreach", node.loc?.start.offset ?? 0, node.source.loc?.start.offset ?? source.length, filename, source) });
|
|
946
|
+
}
|
|
315
947
|
/**
|
|
316
948
|
* Converts an ordered PHP block with its own adaptation scope.
|
|
317
949
|
* @param {import("php-parser").Block} node - PHP parser block.
|
|
318
|
-
* @param {Set<string>} visible - Names visible on block entry.
|
|
319
950
|
* @param {string} filename - Source filename.
|
|
320
951
|
* @param {string} source - Complete source.
|
|
952
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
321
953
|
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
322
954
|
*/
|
|
323
|
-
function convertBlock(node,
|
|
955
|
+
function convertBlock(node, filename, source, context) {
|
|
324
956
|
return {
|
|
325
957
|
kind: "Block",
|
|
326
958
|
location: nodeLocation(node, filename, source),
|
|
327
|
-
statements: node.children.map((statement) => convertStatement(statement,
|
|
959
|
+
statements: node.children.map((statement) => convertStatement(statement, filename, source, context))
|
|
328
960
|
};
|
|
329
961
|
}
|
|
330
962
|
/**
|
|
@@ -334,85 +966,688 @@ function convertBlock(node, visible, filename, source) {
|
|
|
334
966
|
* @param {import("../semantic/types.js").SourceLocation} location - Source location.
|
|
335
967
|
* @param {string} filename - Source filename.
|
|
336
968
|
* @param {string} source - Complete source.
|
|
337
|
-
* @
|
|
969
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
|
|
970
|
+
* @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
|
|
338
971
|
*/
|
|
339
|
-
function convertType(sourceType, subject, location, filename, source) {
|
|
972
|
+
function convertType(sourceType, subject, location, filename, source, recordNames = new Map()) {
|
|
340
973
|
if (!sourceType)
|
|
341
974
|
return requireSourceScalarType("php", undefined, subject, location);
|
|
342
975
|
if (sourceType.kind != "typereference" && sourceType.kind != "name" && sourceType.kind != "identifier") {
|
|
343
976
|
return unsupportedSyntax("php", "unsupported scalar type", nodeLocation(sourceType, filename, source));
|
|
344
977
|
}
|
|
345
978
|
const typeName = /** @type {import("php-parser").TypeReference | import("php-parser").Name | import("php-parser").Identifier} */ (sourceType).name;
|
|
346
|
-
|
|
979
|
+
const typeLocation = nodeLocation(sourceType, filename, source);
|
|
980
|
+
const declaration = recordNames.get(typeName);
|
|
981
|
+
if (declaration?.id)
|
|
982
|
+
return declaration.kind == "ClassDeclaration"
|
|
983
|
+
? referenceType(declaration.id, typeLocation)
|
|
984
|
+
: declaration.kind == "EffectResourceDeclaration"
|
|
985
|
+
? ownedResourceType(declaration.id, typeLocation)
|
|
986
|
+
: recordType(declaration.id, typeLocation);
|
|
987
|
+
return requireSourceScalarType("php", typeName, subject, location, typeLocation);
|
|
347
988
|
}
|
|
348
989
|
/**
|
|
349
|
-
*
|
|
990
|
+
* Reads the exact PHPDoc container signature attached to one function.
|
|
991
|
+
* @param {import("php-parser").Function} node - Function declaration.
|
|
992
|
+
* @param {string} filename - Source filename.
|
|
993
|
+
* @param {string} source - Complete source.
|
|
994
|
+
* @param {string} [ownerId] - Stable declaration identity.
|
|
995
|
+
* @returns {{parameters: Map<string, {location: import("../semantic/types.js").SourceLocation, sourceType: string}>, returnType: {location: import("../semantic/types.js").SourceLocation, sourceType: string} | undefined, typeParameters?: import("../semantic/types.js").TypeParameter[]}} Documented types.
|
|
996
|
+
*/
|
|
997
|
+
function functionDocumentedTypes(node, filename, source, ownerId) {
|
|
998
|
+
const comment = node.leadingComments?.at(-1);
|
|
999
|
+
if (!comment || comment.kind != "commentblock" || !comment.loc || !node.loc ||
|
|
1000
|
+
!/^\s*$/u.test(source.slice(comment.loc.end.offset, node.loc.start.offset)))
|
|
1001
|
+
return { parameters: new Map(), returnType: undefined };
|
|
1002
|
+
const block = parseComment(comment.value)[0];
|
|
1003
|
+
const tags = block?.tags ?? [];
|
|
1004
|
+
const parameterTags = tags.filter((tag) => tag.tag == "param");
|
|
1005
|
+
const returnTags = tags.filter((tag) => tag.tag == "return" || tag.tag == "returns");
|
|
1006
|
+
const templateTags = tags.filter((tag) => tag.tag == "template");
|
|
1007
|
+
const malformedTemplate = tags.find((tag) => tag.tag.startsWith("template") && tag.tag != "template");
|
|
1008
|
+
const malformed = tags.some((tag) => !["param", "return", "returns", "template"].includes(tag.tag)) || returnTags.length > 1 ||
|
|
1009
|
+
parameterTags.some((tag) => tag.type != "" || !/^\$[A-Za-z_][A-Za-z0-9_]*$/u.test(tag.description)) ||
|
|
1010
|
+
returnTags.some((tag) => tag.type != "" || tag.description != "") || malformedTemplate ||
|
|
1011
|
+
templateTags.some((tag) => !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(tag.name) || tag.type != "" || tag.description != "") ||
|
|
1012
|
+
templateTags.length > 0 && !ownerId;
|
|
1013
|
+
if (malformed)
|
|
1014
|
+
return unsupportedSyntax("php", "malformed function type annotation", nodeLocation(node, filename, source));
|
|
1015
|
+
const parameters = new Map(parameterTags.map((tag) => [tag.description.slice(1), {
|
|
1016
|
+
location: commentTagLocation(comment, tag, "name", filename, source),
|
|
1017
|
+
sourceType: tag.name
|
|
1018
|
+
}]));
|
|
1019
|
+
if (parameters.size != parameterTags.length) {
|
|
1020
|
+
return unsupportedSyntax("php", "duplicate parameter annotation", nodeLocation(node, filename, source));
|
|
1021
|
+
}
|
|
1022
|
+
const returnTag = returnTags[0];
|
|
1023
|
+
const typeParameters = templateTags.map((tag, index) => {
|
|
1024
|
+
const location = commentTagLocation(comment, tag, "name", filename, source);
|
|
1025
|
+
return withParserRanges({ id: `${ownerId}:type:${index}`, kind: /** @type {const} */ ("TypeParameter"), location, name: tag.name }, { name: location });
|
|
1026
|
+
});
|
|
1027
|
+
return {
|
|
1028
|
+
parameters,
|
|
1029
|
+
returnType: returnTag ? {
|
|
1030
|
+
location: commentTagLocation(comment, returnTag, "name", filename, source),
|
|
1031
|
+
sourceType: returnTag.name
|
|
1032
|
+
} : undefined,
|
|
1033
|
+
...(typeParameters.length > 0 ? { typeParameters } : {})
|
|
1034
|
+
};
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* Reads an optional exact class-level PHPDoc template list.
|
|
1038
|
+
* @param {import("php-parser").Class} node - Class declaration.
|
|
1039
|
+
* @param {string} ownerId - Stable record identity.
|
|
1040
|
+
* @param {string} filename - Source filename.
|
|
1041
|
+
* @param {string} source - Complete source.
|
|
1042
|
+
* @returns {import("../semantic/types.js").TypeParameter[] | undefined} Ordered parameters.
|
|
1043
|
+
*/
|
|
1044
|
+
function classDocumentedTypeParameters(node, ownerId, filename, source) {
|
|
1045
|
+
const documented = functionDocumentedTypes(
|
|
1046
|
+
/** @type {import("php-parser").Function} */ ( /** @type {unknown} */(node)), filename, source, ownerId);
|
|
1047
|
+
if (documented.parameters.size || documented.returnType) {
|
|
1048
|
+
return unsupportedSyntax("php", "function type annotation on record declaration", nodeLocation(node, filename, source));
|
|
1049
|
+
}
|
|
1050
|
+
return documented.typeParameters;
|
|
1051
|
+
}
|
|
1052
|
+
/**
|
|
1053
|
+
* Returns a native PHP type name from one supported parser node.
|
|
1054
|
+
* @param {import("php-parser").Node | null} type - Native type node.
|
|
1055
|
+
* @returns {string | undefined} Type name.
|
|
1056
|
+
*/
|
|
1057
|
+
function phpTypeName(type) {
|
|
1058
|
+
if (!type || !["typereference", "name", "identifier"].includes(type.kind))
|
|
1059
|
+
return undefined;
|
|
1060
|
+
return /** @type {import("php-parser").TypeReference | import("php-parser").Name | import("php-parser").Identifier} */ (type).name;
|
|
1061
|
+
}
|
|
1062
|
+
/**
|
|
1063
|
+
* Wraps one parser-declared canonical PHP nullable type.
|
|
1064
|
+
* @param {import("../semantic/types.js").SemanticValueType} valueType - Present-value semantic type.
|
|
1065
|
+
* @param {import("php-parser").Node} sourceType - Native parser type node.
|
|
1066
|
+
* @param {number} ownerStart - Earliest owning parser offset.
|
|
1067
|
+
* @param {string} filename - Source filename.
|
|
1068
|
+
* @param {string} source - Complete source.
|
|
1069
|
+
* @returns {import("../semantic/types.js").OptionalType} Optional semantic type.
|
|
1070
|
+
*/
|
|
1071
|
+
function nullableType(valueType, sourceType, ownerStart, filename, source) {
|
|
1072
|
+
if (!sourceType.loc)
|
|
1073
|
+
throw new Error("PHP parser omitted nullable type location.");
|
|
1074
|
+
const valueLocation = nodeLocation(sourceType, filename, source);
|
|
1075
|
+
const marker = tokenLocation("?", ownerStart, sourceType.loc.start.offset, filename, source);
|
|
1076
|
+
if (marker.end.offset != valueLocation.start.offset) {
|
|
1077
|
+
return unsupportedSyntax("php", "noncanonical nullable type", marker);
|
|
1078
|
+
}
|
|
1079
|
+
return optionalType(valueType, locationFromOffsets(filename, source, marker.start.offset, valueLocation.end.offset), valueLocation);
|
|
1080
|
+
}
|
|
1081
|
+
/**
|
|
1082
|
+
* Converts one explicit PHP function return type.
|
|
1083
|
+
* @param {import("php-parser").Node | null} sourceType - PHP return type node.
|
|
1084
|
+
* @param {string} subject - Typed function return.
|
|
1085
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Function location.
|
|
1086
|
+
* @param {string} filename - Source filename.
|
|
1087
|
+
* @param {string} source - Complete source.
|
|
1088
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
|
|
1089
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
|
|
1090
|
+
*/
|
|
1091
|
+
function convertReturnType(sourceType, subject, location, filename, source, recordNames = new Map()) {
|
|
1092
|
+
if (!sourceType)
|
|
1093
|
+
return requireSourceReturnType("php", undefined, subject, location);
|
|
1094
|
+
if (sourceType.kind != "typereference" && sourceType.kind != "name" && sourceType.kind != "identifier") {
|
|
1095
|
+
return unsupportedSyntax("php", "unsupported return type", nodeLocation(sourceType, filename, source));
|
|
1096
|
+
}
|
|
1097
|
+
const typeName = /** @type {import("php-parser").TypeReference | import("php-parser").Name | import("php-parser").Identifier} */ (sourceType).name;
|
|
1098
|
+
const declaration = recordNames.get(typeName);
|
|
1099
|
+
if (declaration?.id)
|
|
1100
|
+
return declaration.kind == "ClassDeclaration"
|
|
1101
|
+
? referenceType(declaration.id, nodeLocation(sourceType, filename, source))
|
|
1102
|
+
: declaration.kind == "EffectResourceDeclaration"
|
|
1103
|
+
? ownedResourceType(declaration.id, nodeLocation(sourceType, filename, source))
|
|
1104
|
+
: recordType(declaration.id, nodeLocation(sourceType, filename, source));
|
|
1105
|
+
return requireSourceReturnType("php", typeName, subject, location, nodeLocation(sourceType, filename, source));
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Converts the explicit type signature of one PHP function before any body expressions.
|
|
350
1109
|
* @param {import("php-parser").Function} node - PHP function node.
|
|
351
1110
|
* @param {string} filename - Source filename.
|
|
352
1111
|
* @param {string} source - Complete source.
|
|
353
|
-
* @
|
|
1112
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
|
|
1113
|
+
* @param {string} ownerId - Stable function identity.
|
|
1114
|
+
* @returns {PhpFunctionSignature} Typed function signature.
|
|
354
1115
|
*/
|
|
355
|
-
function
|
|
1116
|
+
function convertFunctionSignature(node, filename, source, recordNames, ownerId) {
|
|
356
1117
|
const location = nodeLocation(node, filename, source);
|
|
357
1118
|
const name = typeof node.name == "string" ? node.name : node.name.name;
|
|
358
1119
|
if (!node.body) {
|
|
359
1120
|
return unsupportedSyntax("php", "function body", location);
|
|
360
1121
|
}
|
|
1122
|
+
const documented = functionDocumentedTypes(node, filename, source, ownerId);
|
|
1123
|
+
const typeParameterNames = new Map((documented.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
|
|
361
1124
|
const parameters = node.arguments.map((parameter) => {
|
|
362
1125
|
const parameterLocation = nodeLocation(parameter, filename, source);
|
|
363
1126
|
const parameterName = typeof parameter.name == "string" ? parameter.name : parameter.name.name;
|
|
364
|
-
if (parameter.
|
|
365
|
-
return unsupportedSyntax("php", "
|
|
1127
|
+
if (parameter.byref)
|
|
1128
|
+
return unsupportedSyntax("php", "by-reference parameter", parameterLocation);
|
|
1129
|
+
if (parameter.variadic)
|
|
1130
|
+
return unsupportedSyntax("php", "variadic parameter", parameterLocation);
|
|
1131
|
+
if (parameter.value)
|
|
1132
|
+
return unsupportedSyntax("php", "default parameter", parameterLocation);
|
|
366
1133
|
const parameterNode = typeof parameter.name == "string" ? parameter : parameter.name;
|
|
1134
|
+
const documentedType = documented.parameters.get(parameterName);
|
|
1135
|
+
const nativeType = phpTypeName(parameter.type);
|
|
1136
|
+
let parameterType = documentedType
|
|
1137
|
+
? documentedValueType({ language: "php", location: documentedType.location, ownerLocation: parameterLocation, source,
|
|
1138
|
+
records: recordNames, sourceType: documentedType.sourceType, subject: `Parameter '${parameterName}'`, typeParameters: typeParameterNames })
|
|
1139
|
+
: convertType(parameter.type, `Parameter '${parameterName}'`, parameterLocation, filename, source, recordNames);
|
|
1140
|
+
if (nativeType == "array" && !documentedType)
|
|
1141
|
+
return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
|
|
1142
|
+
if (documentedType && !phpDocumentedNativeTypeMatches(nativeType, parameter.nullable, parameterType, recordNames)) {
|
|
1143
|
+
return unsupportedSyntax("php", "documented parameter type incompatible with native type", documentedType.location);
|
|
1144
|
+
}
|
|
1145
|
+
if (parameter.nullable && parameterType.kind != "OptionalType") {
|
|
1146
|
+
if (!parameter.type)
|
|
1147
|
+
return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
|
|
1148
|
+
parameterType = nullableType(parameterType, parameter.type, parameter.loc?.start.offset ?? 0, filename, source);
|
|
1149
|
+
}
|
|
1150
|
+
else if (!parameter.nullable && parameterType.kind == "OptionalType" &&
|
|
1151
|
+
parameterType.valueType.kind != "TypeVariableReference") {
|
|
1152
|
+
return unsupportedSyntax("php", "optional annotation without nullable native type", documentedType?.location ?? parameterLocation);
|
|
1153
|
+
}
|
|
367
1154
|
const semanticParameter = {
|
|
368
1155
|
kind: /** @type {const} */ ("Parameter"),
|
|
369
1156
|
location: parameterLocation,
|
|
370
1157
|
name: parameterName,
|
|
371
|
-
type:
|
|
1158
|
+
type: parameterType
|
|
372
1159
|
};
|
|
373
1160
|
return withParserRanges(semanticParameter, { name: nodeLocation(parameterNode, filename, source) });
|
|
374
1161
|
});
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
1162
|
+
const extraDocumentedParameter = [...documented.parameters.keys()].find((name) => !node.arguments.some((parameter) => (typeof parameter.name == "string" ? parameter.name : parameter.name.name) == name));
|
|
1163
|
+
if (extraDocumentedParameter)
|
|
1164
|
+
return unsupportedSyntax("php", `annotation for unknown parameter '${extraDocumentedParameter}'`, location);
|
|
1165
|
+
if (node.byref)
|
|
1166
|
+
return unsupportedSyntax("php", "by-reference return", location);
|
|
379
1167
|
const nameNode = typeof node.name == "string" ? node : node.name;
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
1168
|
+
const nativeReturnType = phpTypeName(node.type);
|
|
1169
|
+
let returnType;
|
|
1170
|
+
if (documented.returnType) {
|
|
1171
|
+
returnType = documentedValueType({ language: "php", location: documented.returnType.location, ownerLocation: location, source,
|
|
1172
|
+
records: recordNames, sourceType: documented.returnType.sourceType, subject: `Function '${name}' return`, typeParameters: typeParameterNames });
|
|
1173
|
+
if (!phpDocumentedNativeTypeMatches(nativeReturnType, node.nullable, returnType, recordNames)) {
|
|
1174
|
+
return unsupportedSyntax("php", "documented return type incompatible with native type", documented.returnType.location);
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
else {
|
|
1178
|
+
if (nativeReturnType == "array")
|
|
1179
|
+
return missingType("php", `Function '${name}' return`, location);
|
|
1180
|
+
returnType = convertReturnType(node.type, `Function '${name}' return`, location, filename, source, recordNames);
|
|
1181
|
+
}
|
|
1182
|
+
if (node.nullable && returnType.kind != "OptionalType") {
|
|
1183
|
+
if (!node.type)
|
|
1184
|
+
return missingType("php", `Function '${name}' return`, location);
|
|
1185
|
+
const typeStart = node.type.loc?.start.offset ?? 0;
|
|
1186
|
+
returnType = nullableType(
|
|
1187
|
+
/** @type {import("../semantic/types.js").SemanticValueType} */ (returnType), node.type, Math.max(node.loc?.start.offset ?? 0, typeStart - 2), filename, source);
|
|
1188
|
+
}
|
|
1189
|
+
else if (!node.nullable && returnType.kind == "OptionalType" &&
|
|
1190
|
+
returnType.valueType.kind != "TypeVariableReference") {
|
|
1191
|
+
return unsupportedSyntax("php", "optional annotation without nullable native return type", documented.returnType?.location ?? location);
|
|
1192
|
+
}
|
|
1193
|
+
return {
|
|
383
1194
|
location,
|
|
384
1195
|
name,
|
|
1196
|
+
nameLocation: nodeLocation(nameNode, filename, source),
|
|
385
1197
|
parameters,
|
|
386
|
-
returnType
|
|
387
|
-
|
|
1198
|
+
returnType,
|
|
1199
|
+
...(documented.typeParameters ? { typeParameters: documented.typeParameters } : {})
|
|
1200
|
+
};
|
|
1201
|
+
}
|
|
1202
|
+
/**
|
|
1203
|
+
* Checks the exact runtime carrier permitted beside a precise PHPDoc type.
|
|
1204
|
+
* @param {string | undefined} nativeType - Native PHP type name.
|
|
1205
|
+
* @param {boolean} nativeNullable - Whether the native carrier has PHP's nullable marker.
|
|
1206
|
+
* @param {import("../semantic/types.js").SemanticValueType} documentedType - Exact semantic document type.
|
|
1207
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} records - Visible nominal declarations by name.
|
|
1208
|
+
* @returns {boolean} Whether the native carrier agrees without changing meaning.
|
|
1209
|
+
*/
|
|
1210
|
+
function phpDocumentedNativeTypeMatches(nativeType, nativeNullable, documentedType, records) {
|
|
1211
|
+
if (documentedType.kind == "OptionalType") {
|
|
1212
|
+
if (documentedType.valueType.kind == "TypeVariableReference") {
|
|
1213
|
+
return nativeType === undefined && !nativeNullable;
|
|
1214
|
+
}
|
|
1215
|
+
return nativeNullable && phpDocumentedNativeTypeMatches(nativeType, false, documentedType.valueType, records);
|
|
1216
|
+
}
|
|
1217
|
+
if (nativeNullable)
|
|
1218
|
+
return false;
|
|
1219
|
+
if (documentedType.kind == "TypeVariableReference")
|
|
1220
|
+
return nativeType === undefined;
|
|
1221
|
+
if (documentedType.kind == "TypeReference") {
|
|
1222
|
+
return nativeType !== undefined && sourceScalarType("php", nativeType)?.name == documentedType.name;
|
|
1223
|
+
}
|
|
1224
|
+
if (documentedType.kind == "ListType" || documentedType.kind == "MapType" || documentedType.kind == "OrderedMapType") {
|
|
1225
|
+
return nativeType == "array";
|
|
1226
|
+
}
|
|
1227
|
+
if (documentedType.kind == "RecordType") {
|
|
1228
|
+
return nativeType !== undefined && records.get(nativeType)?.id == documentedType.declarationId;
|
|
1229
|
+
}
|
|
1230
|
+
if (documentedType.kind == "ReferenceType") {
|
|
1231
|
+
return nativeType !== undefined && records.get(nativeType)?.id == documentedType.declarationId;
|
|
1232
|
+
}
|
|
1233
|
+
return false;
|
|
1234
|
+
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Converts a PHP function body using the already-proved module signatures.
|
|
1237
|
+
* @param {import("php-parser").Function} node - PHP function node.
|
|
1238
|
+
* @param {PhpFunctionSignature} signature - Preconverted explicit signature.
|
|
1239
|
+
* @param {Map<string, PhpFunctionSignature>} functions - Module function signatures.
|
|
1240
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
|
|
1241
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
|
|
1242
|
+
* @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
|
|
1243
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
|
|
1244
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Error declarations by identity.
|
|
1245
|
+
* @param {string} filename - Source filename.
|
|
1246
|
+
* @param {string} source - Complete source.
|
|
1247
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
1248
|
+
*/
|
|
1249
|
+
function convertFunction(node, signature, functions, recordNames, records, classes, errorNames, errors, filename, source) {
|
|
1250
|
+
if (!node.body)
|
|
1251
|
+
return unsupportedSyntax("php", "function body", signature.location);
|
|
1252
|
+
const context = {
|
|
1253
|
+
bindings: new Map(signature.parameters.map((parameter) => [parameter.name, parameter.type])),
|
|
1254
|
+
classes,
|
|
1255
|
+
errorNames,
|
|
1256
|
+
errors,
|
|
1257
|
+
functions,
|
|
1258
|
+
orderedMapDeclarations: orderedMapDeclarationsForPhp(node.body),
|
|
1259
|
+
recordNames,
|
|
1260
|
+
records,
|
|
1261
|
+
returnType: signature.returnType,
|
|
1262
|
+
typeParameters: new Map((signature.typeParameters ?? []).map((parameter) => [parameter.name, parameter]))
|
|
1263
|
+
};
|
|
1264
|
+
return withParserRanges({
|
|
1265
|
+
body: convertBlock(node.body, filename, source, context),
|
|
1266
|
+
kind: "FunctionDeclaration",
|
|
1267
|
+
location: signature.location,
|
|
1268
|
+
name: signature.name,
|
|
1269
|
+
parameters: signature.parameters,
|
|
1270
|
+
returnType: signature.returnType,
|
|
1271
|
+
...(signature.typeParameters ? { typeParameters: signature.typeParameters } : {})
|
|
1272
|
+
}, { name: signature.nameLocation });
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Resolves parser-owned key/value loops to exact declarations inside one lexical owner.
|
|
1276
|
+
* Ambiguous same-name declarations produce no evidence and fail during loop conversion.
|
|
1277
|
+
* @param {unknown} value - Function body or entry-point subtree.
|
|
1278
|
+
* @returns {Set<object>} Exact pair-iterated parser declarations.
|
|
1279
|
+
*/
|
|
1280
|
+
function orderedMapDeclarationsForPhp(value) {
|
|
1281
|
+
/** @type {{declaration: object, name: string, offset: number}[]} */
|
|
1282
|
+
const declarations = [];
|
|
1283
|
+
/** @type {{name: string, offset: number}[]} */
|
|
1284
|
+
const receivers = [];
|
|
1285
|
+
const seen = new WeakSet();
|
|
1286
|
+
/**
|
|
1287
|
+
* Visits one parser candidate.
|
|
1288
|
+
* @param {unknown} candidate - Parser candidate.
|
|
1289
|
+
*/
|
|
1290
|
+
const visit = (candidate) => {
|
|
1291
|
+
if (!candidate || typeof candidate != "object" || seen.has(candidate))
|
|
1292
|
+
return;
|
|
1293
|
+
seen.add(candidate);
|
|
1294
|
+
const kind = Reflect.get(candidate, "kind");
|
|
1295
|
+
if (kind == "function" || kind == "class")
|
|
1296
|
+
return;
|
|
1297
|
+
if (kind == "assign") {
|
|
1298
|
+
const variable = Reflect.get(candidate, "left");
|
|
1299
|
+
if (Reflect.get(variable, "kind") == "variable" && typeof Reflect.get(variable, "name") == "string") {
|
|
1300
|
+
declarations.push({
|
|
1301
|
+
declaration: candidate,
|
|
1302
|
+
name: Reflect.get(variable, "name"),
|
|
1303
|
+
offset: Reflect.get(variable, "loc")?.start.offset
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
else if (kind == "foreach") {
|
|
1308
|
+
const receiver = Reflect.get(candidate, "source");
|
|
1309
|
+
if (Reflect.get(receiver, "kind") == "variable" && typeof Reflect.get(receiver, "name") == "string" &&
|
|
1310
|
+
Reflect.get(candidate, "key"))
|
|
1311
|
+
receivers.push({
|
|
1312
|
+
name: Reflect.get(receiver, "name"),
|
|
1313
|
+
offset: Reflect.get(candidate, "loc")?.start.offset
|
|
1314
|
+
});
|
|
1315
|
+
}
|
|
1316
|
+
for (const [key, child] of Object.entries(candidate)) {
|
|
1317
|
+
if (["loc", "leadingComments", "trailingComments"].includes(key))
|
|
1318
|
+
continue;
|
|
1319
|
+
if (Array.isArray(child)) {
|
|
1320
|
+
for (const item of child)
|
|
1321
|
+
visit(item);
|
|
1322
|
+
}
|
|
1323
|
+
else
|
|
1324
|
+
visit(child);
|
|
1325
|
+
}
|
|
1326
|
+
};
|
|
1327
|
+
visit(value);
|
|
1328
|
+
const selected = new Set();
|
|
1329
|
+
for (const receiver of receivers) {
|
|
1330
|
+
const matches = declarations.filter(({ name, offset }) => name == receiver.name && offset < receiver.offset);
|
|
1331
|
+
if (matches.length == 1)
|
|
1332
|
+
selected.add(matches[0].declaration);
|
|
1333
|
+
}
|
|
1334
|
+
return selected;
|
|
1335
|
+
}
|
|
1336
|
+
/**
|
|
1337
|
+
* Converts one exact final RuntimeException subclass.
|
|
1338
|
+
* @param {import("php-parser").Class} node - PHP class declaration.
|
|
1339
|
+
* @param {import("../semantic/types.js").ErrorDeclaration} declaration - Predeclared semantic error.
|
|
1340
|
+
* @param {string} filename - Source filename.
|
|
1341
|
+
* @param {string} source - Complete source.
|
|
1342
|
+
* @returns {import("../semantic/types.js").ErrorDeclaration} Semantic error declaration.
|
|
1343
|
+
*/
|
|
1344
|
+
function convertPhpError(node, declaration, filename, source) {
|
|
1345
|
+
const location = nodeLocation(node, filename, source);
|
|
1346
|
+
const parent = node.extends;
|
|
1347
|
+
const parentName = parent?.kind == "name" ? /** @type {import("php-parser").Name} */ ( /** @type {unknown} */(parent)) : undefined;
|
|
1348
|
+
if (node.isAnonymous || !node.isFinal || node.isReadonly || node.isAbstract || node.implements?.length ||
|
|
1349
|
+
node.attrGroups.length || node.body.length != 0 || !parentName ||
|
|
1350
|
+
!(parentName.name == "RuntimeException" && parentName.resolution == "uqn" ||
|
|
1351
|
+
parentName.name == "\\RuntimeException" && parentName.resolution == "fqn")) {
|
|
1352
|
+
return unsupportedSyntax("php", "noncanonical typed error declaration", location);
|
|
1353
|
+
}
|
|
1354
|
+
const nameNode = typeof node.name == "string" ? node : node.name;
|
|
1355
|
+
return withParserRanges(declaration, { name: nodeLocation(nameNode, filename, source), type: nodeLocation(parentName, filename, source) });
|
|
1356
|
+
}
|
|
1357
|
+
/**
|
|
1358
|
+
* Reads one exact public PHP constructor or instance-method signature.
|
|
1359
|
+
* @param {import("php-parser").Method} node - Parser-owned method.
|
|
1360
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Visible nominal declarations.
|
|
1361
|
+
* @param {string} ownerId - Stable callable identity.
|
|
1362
|
+
* @param {boolean} constructor - Whether this is the sole constructor.
|
|
1363
|
+
* @param {string} filename - Source filename.
|
|
1364
|
+
* @param {string} source - Complete source.
|
|
1365
|
+
* @returns {{location: import("../semantic/types.js").SourceLocation, name: string, nameLocation: import("../semantic/types.js").SourceLocation, parameters: import("../semantic/types.js").Parameter[], returnType?: import("../semantic/types.js").SemanticFunctionReturnType}} Exact signature.
|
|
1366
|
+
*/
|
|
1367
|
+
function convertPhpClassCallableSignature(node, nominalNames, ownerId, constructor, filename, source) {
|
|
1368
|
+
const location = nodeLocation(node, filename, source);
|
|
1369
|
+
const name = typeof node.name == "string" ? node.name : node.name.name;
|
|
1370
|
+
if (!constructor && /^__/u.test(name))
|
|
1371
|
+
return unsupportedSyntax("php", `reserved reference method '${name}'`, location);
|
|
1372
|
+
if (node.visibility != "public" || node.isStatic || node.isAbstract || node.isFinal || Reflect.get(node, "isReadonly") || node.byref ||
|
|
1373
|
+
node.attrGroups.length || !node.body || constructor != (name == "__construct")) {
|
|
1374
|
+
return unsupportedSyntax("php", "noncanonical reference class callable", location);
|
|
1375
|
+
}
|
|
1376
|
+
const documented = functionDocumentedTypes(/** @type {import("php-parser").Function} */ ( /** @type {unknown} */(node)), filename, source, ownerId);
|
|
1377
|
+
if (documented.typeParameters?.length)
|
|
1378
|
+
return unsupportedSyntax("php", "generic reference class callable", location);
|
|
1379
|
+
if (constructor && (node.type || node.nullable || documented.returnType)) {
|
|
1380
|
+
return unsupportedSyntax("php", "constructor return annotation", location);
|
|
1381
|
+
}
|
|
1382
|
+
const parameters = node.arguments.map((parameter) => {
|
|
1383
|
+
const parameterLocation = nodeLocation(parameter, filename, source);
|
|
1384
|
+
const parameterName = typeof parameter.name == "string" ? parameter.name : parameter.name.name;
|
|
1385
|
+
if (parameter.byref || parameter.variadic || parameter.value || parameter.flags || parameter.readonly ||
|
|
1386
|
+
parameter.hooks.length || parameter.attrGroups.length) {
|
|
1387
|
+
return unsupportedSyntax("php", "noncanonical reference class parameter", parameterLocation);
|
|
1388
|
+
}
|
|
1389
|
+
const documentedType = documented.parameters.get(parameterName);
|
|
1390
|
+
const nativeType = phpTypeName(parameter.type);
|
|
1391
|
+
let type = documentedType
|
|
1392
|
+
? documentedValueType({ language: "php", location: documentedType.location, ownerLocation: parameterLocation,
|
|
1393
|
+
records: nominalNames, source, sourceType: documentedType.sourceType, subject: `Parameter '${parameterName}'` })
|
|
1394
|
+
: convertType(parameter.type, `Parameter '${parameterName}'`, parameterLocation, filename, source, nominalNames);
|
|
1395
|
+
if (nativeType == "array" && !documentedType)
|
|
1396
|
+
return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
|
|
1397
|
+
if (documentedType && !phpDocumentedNativeTypeMatches(nativeType, parameter.nullable, type, nominalNames)) {
|
|
1398
|
+
return unsupportedSyntax("php", "documented parameter type incompatible with native type", documentedType.location);
|
|
1399
|
+
}
|
|
1400
|
+
if (parameter.nullable && type.kind != "OptionalType") {
|
|
1401
|
+
if (!parameter.type)
|
|
1402
|
+
return missingType("php", `Parameter '${parameterName}'`, parameterLocation);
|
|
1403
|
+
type = nullableType(type, parameter.type, parameter.loc?.start.offset ?? 0, filename, source);
|
|
1404
|
+
}
|
|
1405
|
+
else if (!parameter.nullable && type.kind == "OptionalType") {
|
|
1406
|
+
return unsupportedSyntax("php", "optional annotation without nullable native type", documentedType?.location ?? parameterLocation);
|
|
1407
|
+
}
|
|
1408
|
+
const nameNode = typeof parameter.name == "string" ? parameter : parameter.name;
|
|
1409
|
+
return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: parameterLocation,
|
|
1410
|
+
name: parameterName, type }, { name: nodeLocation(nameNode, filename, source) });
|
|
1411
|
+
});
|
|
1412
|
+
if ([...documented.parameters.keys()].some((parameterName) => !node.arguments.some((parameter) => (typeof parameter.name == "string" ? parameter.name : parameter.name.name) == parameterName))) {
|
|
1413
|
+
return unsupportedSyntax("php", "method PHPDoc parameter mismatch", location);
|
|
1414
|
+
}
|
|
1415
|
+
const nameNode = typeof node.name == "string" ? node : node.name;
|
|
1416
|
+
if (constructor)
|
|
1417
|
+
return { location, name: "constructor", nameLocation: nodeLocation(nameNode, filename, source), parameters };
|
|
1418
|
+
let returnType;
|
|
1419
|
+
const nativeReturnType = phpTypeName(node.type);
|
|
1420
|
+
if (documented.returnType) {
|
|
1421
|
+
returnType = documentedValueType({ language: "php", location: documented.returnType.location, ownerLocation: location,
|
|
1422
|
+
records: nominalNames, source, sourceType: documented.returnType.sourceType, subject: `Method '${name}' return` });
|
|
1423
|
+
if (!phpDocumentedNativeTypeMatches(nativeReturnType, node.nullable, returnType, nominalNames)) {
|
|
1424
|
+
return unsupportedSyntax("php", "documented method return type incompatible with native type", documented.returnType.location);
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
else {
|
|
1428
|
+
if (nativeReturnType == "array")
|
|
1429
|
+
return missingType("php", `Method '${name}' return`, location);
|
|
1430
|
+
returnType = convertReturnType(node.type, `Method '${name}' return`, location, filename, source, nominalNames);
|
|
1431
|
+
}
|
|
1432
|
+
if (node.nullable && returnType.kind != "OptionalType") {
|
|
1433
|
+
if (!node.type)
|
|
1434
|
+
return missingType("php", `Method '${name}' return`, location);
|
|
1435
|
+
returnType = nullableType(/** @type {import("../semantic/types.js").SemanticValueType} */ (returnType), node.type, node.type.loc?.start.offset ?? 0, filename, source);
|
|
1436
|
+
}
|
|
1437
|
+
else if (!node.nullable && returnType.kind == "OptionalType") {
|
|
1438
|
+
return unsupportedSyntax("php", "optional annotation without nullable native return type", documented.returnType?.location ?? location);
|
|
1439
|
+
}
|
|
1440
|
+
return { location, name, nameLocation: nodeLocation(nameNode, filename, source), parameters, returnType };
|
|
1441
|
+
}
|
|
1442
|
+
/**
|
|
1443
|
+
* Converts the bounded final/private-field PHP reference-class profile.
|
|
1444
|
+
* @param {import("php-parser").Class} node - Parser class.
|
|
1445
|
+
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
|
|
1446
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Visible nominal declarations.
|
|
1447
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
|
|
1448
|
+
* @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
|
|
1449
|
+
* @param {Map<string, PhpFunctionSignature>} functions - Top-level signatures.
|
|
1450
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Errors by name.
|
|
1451
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Errors by identity.
|
|
1452
|
+
* @param {string} filename - Source filename.
|
|
1453
|
+
* @param {string} source - Complete source.
|
|
1454
|
+
* @returns {import("../semantic/types.js").ClassDeclaration} Semantic class.
|
|
1455
|
+
*/
|
|
1456
|
+
function convertPhpReferenceClass(node, declaration, nominalNames, records, classes, functions, errorNames, errors, filename, source) {
|
|
1457
|
+
const location = nodeLocation(node, filename, source);
|
|
1458
|
+
if (node.isAnonymous || !node.isFinal || node.isReadonly || node.isAbstract || node.extends || node.implements?.length ||
|
|
1459
|
+
node.attrGroups.length)
|
|
1460
|
+
return unsupportedSyntax("php", "reference class inheritance or noncanonical modifier", location);
|
|
1461
|
+
const fieldStatements = node.body.filter((member) => member.kind == "propertystatement");
|
|
1462
|
+
const methodNodes = /** @type {import("php-parser").Method[]} */ (node.body.filter((member) => member.kind == "method"));
|
|
1463
|
+
const constructors = methodNodes.filter((method) => (typeof method.name == "string" ? method.name : method.name.name) == "__construct");
|
|
1464
|
+
const ordinaryMethods = methodNodes.filter((method) => !constructors.includes(method));
|
|
1465
|
+
if (constructors.length != 1 || fieldStatements.length == 0 || fieldStatements.length + methodNodes.length != node.body.length) {
|
|
1466
|
+
return unsupportedSyntax("php", "reference class requires private fields, one constructor, and ordinary methods", location);
|
|
1467
|
+
}
|
|
1468
|
+
declaration.fields = fieldStatements.map((statement, index) => {
|
|
1469
|
+
const fieldLocation = nodeLocation(statement, filename, source);
|
|
1470
|
+
const properties = Reflect.get(statement, "properties");
|
|
1471
|
+
const property = Array.isArray(properties) && properties.length == 1 ? properties[0] : undefined;
|
|
1472
|
+
const nameNode = property?.name;
|
|
1473
|
+
const name = typeof nameNode == "string" ? nameNode : nameNode?.name;
|
|
1474
|
+
if (Reflect.get(statement, "visibility") != "private" || Reflect.get(statement, "isStatic") ||
|
|
1475
|
+
Reflect.get(statement, "isAbstract") || Reflect.get(statement, "isFinal") || !property ||
|
|
1476
|
+
typeof name != "string" || property.value || property.readonly || property.nullable || property.attrGroups?.length ||
|
|
1477
|
+
property.hooks?.length)
|
|
1478
|
+
return unsupportedSyntax("php", "noncanonical private instance field", fieldLocation);
|
|
1479
|
+
const type = convertType(property.type, `Private field '${name}'`, fieldLocation, filename, source, nominalNames);
|
|
1480
|
+
return withParserRanges({ id: `${declaration.id}:field:${index}`, kind: /** @type {const} */ ("PrivateField"),
|
|
1481
|
+
location: fieldLocation, name, type }, { name: nodeLocation(typeof nameNode == "string" ? property : nameNode, filename, source) });
|
|
1482
|
+
});
|
|
1483
|
+
const constructorNode = constructors[0];
|
|
1484
|
+
const constructorSignature = convertPhpClassCallableSignature(constructorNode, nominalNames, `${declaration.id}:constructor`, true, filename, source);
|
|
1485
|
+
declaration.constructor = withParserRanges({ body: /** @type {import("../semantic/types.js").Block} */ ({}),
|
|
1486
|
+
id: `${declaration.id}:constructor`, kind: /** @type {const} */ ("ConstructorDeclaration"),
|
|
1487
|
+
location: constructorSignature.location, parameters: constructorSignature.parameters }, { constructor: constructorSignature.nameLocation });
|
|
1488
|
+
const methodSignatures = ordinaryMethods.map((method, index) => convertPhpClassCallableSignature(method, nominalNames, `${declaration.id}:method:${index}`, false, filename, source));
|
|
1489
|
+
declaration.methods = methodSignatures.map((signature, index) => withParserRanges({
|
|
1490
|
+
body: /** @type {import("../semantic/types.js").Block} */ ({}), id: `${declaration.id}:method:${index}`,
|
|
1491
|
+
kind: /** @type {const} */ ("MethodDeclaration"), location: signature.location, name: signature.name,
|
|
1492
|
+
parameters: signature.parameters,
|
|
1493
|
+
returnType: /** @type {import("../semantic/types.js").SemanticFunctionReturnType} */ (signature.returnType)
|
|
1494
|
+
}, { name: signature.nameLocation }));
|
|
1495
|
+
const base = { bindings: new Map(), classes, currentClass: declaration, errorNames, errors, functions,
|
|
1496
|
+
recordNames: nominalNames, records };
|
|
1497
|
+
declaration.constructor.body = convertBlock(/** @type {import("php-parser").Block} */ (constructorNode.body), filename, source, { ...base, bindings: new Map(declaration.constructor.parameters.map((parameter) => [parameter.name, parameter.type])),
|
|
1498
|
+
returnType: { kind: /** @type {const} */ ("TypeReference"), name: /** @type {const} */ ("void") } });
|
|
1499
|
+
for (let index = 0; index < ordinaryMethods.length; index += 1) {
|
|
1500
|
+
const method = declaration.methods[index];
|
|
1501
|
+
method.body = convertBlock(/** @type {import("php-parser").Block} */ (ordinaryMethods[index].body), filename, source, { ...base, bindings: new Map(method.parameters.map((parameter) => [parameter.name, parameter.type])), returnType: method.returnType });
|
|
1502
|
+
}
|
|
1503
|
+
const nameNode = typeof node.name == "string" ? node : node.name;
|
|
1504
|
+
return withParserRanges(declaration, { name: nodeLocation(nameNode, filename, source) });
|
|
1505
|
+
}
|
|
1506
|
+
/**
|
|
1507
|
+
* Converts one exact final readonly promoted-property PHP record.
|
|
1508
|
+
* @param {import("php-parser").Class} node - PHP class declaration.
|
|
1509
|
+
* @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
|
|
1510
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} recordNames - Record declarations by name.
|
|
1511
|
+
* @param {string} filename - Source filename.
|
|
1512
|
+
* @param {string} source - Complete source.
|
|
1513
|
+
* @returns {import("../semantic/types.js").RecordDeclaration} Semantic record.
|
|
1514
|
+
*/
|
|
1515
|
+
function convertPhpRecord(node, declaration, recordNames, filename, source) {
|
|
1516
|
+
const location = nodeLocation(node, filename, source);
|
|
1517
|
+
const generic = (declaration.typeParameters?.length ?? 0) > 0;
|
|
1518
|
+
if (node.isAnonymous || !node.isFinal || node.isReadonly == generic || node.isAbstract || node.extends || node.implements?.length ||
|
|
1519
|
+
node.attrGroups.length)
|
|
1520
|
+
return unsupportedSyntax("php", "noncanonical record class modifiers", location);
|
|
1521
|
+
if (node.body.length < 1 || node.body[0].kind != "method" || !generic && node.body.length != 1) {
|
|
1522
|
+
return unsupportedSyntax("php", "record class body outside one constructor", nodeLocation(node.body[1] ?? node.body[0] ?? node, filename, source));
|
|
1523
|
+
}
|
|
1524
|
+
const constructor = /** @type {import("php-parser").Method} */ (node.body[0]);
|
|
1525
|
+
const typeParameterNames = new Map((declaration.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
|
|
1526
|
+
const constructorName = typeof constructor.name == "string" ? constructor.name : constructor.name.name;
|
|
1527
|
+
if (constructorName != "__construct" || constructor.visibility != "public" || constructor.isStatic || constructor.isAbstract ||
|
|
1528
|
+
constructor.isFinal || Reflect.get(constructor, "isReadonly") || constructor.byref || constructor.type || constructor.nullable ||
|
|
1529
|
+
constructor.attrGroups.length || !constructor.body || constructor.body.children.length != 0) {
|
|
1530
|
+
return unsupportedSyntax("php", "noncanonical record constructor", nodeLocation(constructor, filename, source));
|
|
1531
|
+
}
|
|
1532
|
+
const documented = functionDocumentedTypes(/** @type {import("php-parser").Function} */ ( /** @type {unknown} */(constructor)), filename, source);
|
|
1533
|
+
declaration.fields = constructor.arguments.map((parameter) => {
|
|
1534
|
+
const fieldLocation = nodeLocation(parameter, filename, source);
|
|
1535
|
+
const name = typeof parameter.name == "string" ? parameter.name : parameter.name.name;
|
|
1536
|
+
const documentedType = documented.parameters.get(name);
|
|
1537
|
+
const nativeType = phpTypeName(parameter.type);
|
|
1538
|
+
if (parameter.flags != (generic ? 4 : 1) || parameter.byref || parameter.variadic || parameter.value || parameter.readonly ||
|
|
1539
|
+
parameter.hooks.length || parameter.attrGroups.length) {
|
|
1540
|
+
return unsupportedSyntax("php", "record field outside public promoted-property profile", fieldLocation);
|
|
1541
|
+
}
|
|
1542
|
+
if (nativeType == "array" && !documentedType)
|
|
1543
|
+
return missingType("php", `Record field '${name}'`, fieldLocation);
|
|
1544
|
+
let type = documentedType
|
|
1545
|
+
? documentedValueType({ language: "php", location: documentedType.location, ownerLocation: fieldLocation, records: recordNames,
|
|
1546
|
+
source, sourceType: documentedType.sourceType, subject: `Record field '${name}'`, typeParameters: typeParameterNames })
|
|
1547
|
+
: convertType(parameter.type, `Record field '${name}'`, fieldLocation, filename, source, recordNames);
|
|
1548
|
+
if (documentedType && !phpDocumentedNativeTypeMatches(nativeType, parameter.nullable, type, recordNames)) {
|
|
1549
|
+
return unsupportedSyntax("php", "documented record field type incompatible with native type", documentedType.location);
|
|
1550
|
+
}
|
|
1551
|
+
if (parameter.nullable && type.kind != "OptionalType") {
|
|
1552
|
+
if (!parameter.type)
|
|
1553
|
+
return missingType("php", `Record field '${name}'`, fieldLocation);
|
|
1554
|
+
type = nullableType(type, parameter.type, parameter.loc?.start.offset ?? 0, filename, source);
|
|
1555
|
+
}
|
|
1556
|
+
else if (!parameter.nullable && type.kind == "OptionalType" && type.valueType.kind != "TypeVariableReference") {
|
|
1557
|
+
return unsupportedSyntax("php", "optional annotation without nullable native record field", documentedType?.location ?? fieldLocation);
|
|
1558
|
+
}
|
|
1559
|
+
const field = { kind: /** @type {const} */ ("RecordField"), location: fieldLocation, name, type };
|
|
1560
|
+
const nameNode = typeof parameter.name == "string" ? parameter : parameter.name;
|
|
1561
|
+
return withParserRanges(field, { name: nodeLocation(nameNode, filename, source) });
|
|
1562
|
+
});
|
|
1563
|
+
const extraDocumented = [...documented.parameters.keys()].find((name) => !constructor.arguments.some((parameter) => (typeof parameter.name == "string" ? parameter.name : parameter.name.name) == name));
|
|
1564
|
+
if (extraDocumented || documented.returnType)
|
|
1565
|
+
return unsupportedSyntax("php", "invalid record constructor annotation", location);
|
|
1566
|
+
if (generic)
|
|
1567
|
+
validatePhpGenericRecordGetters(node, declaration, recordNames, filename, source);
|
|
1568
|
+
const nameNode = typeof node.name == "string" ? node : node.name;
|
|
1569
|
+
return withParserRanges(declaration, { name: nodeLocation(nameNode, filename, source) });
|
|
1570
|
+
}
|
|
1571
|
+
/**
|
|
1572
|
+
* Validates the exact accessor half of PHP's documented generic-record profile.
|
|
1573
|
+
* @param {import("php-parser").Class} node - PHP class declaration.
|
|
1574
|
+
* @param {import("../semantic/types.js").RecordDeclaration} declaration - Converted record.
|
|
1575
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} recordNames - Visible records.
|
|
1576
|
+
* @param {string} filename - Source filename.
|
|
1577
|
+
* @param {string} source - Complete source.
|
|
1578
|
+
* @returns {void}
|
|
1579
|
+
*/
|
|
1580
|
+
function validatePhpGenericRecordGetters(node, declaration, recordNames, filename, source) {
|
|
1581
|
+
const getters = node.body.slice(1);
|
|
1582
|
+
const typeParameters = new Map((declaration.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
|
|
1583
|
+
if (getters.length != declaration.fields.length) {
|
|
1584
|
+
return unsupportedSyntax("php", "generic record getter count", nodeLocation(getters[declaration.fields.length] ?? node, filename, source));
|
|
1585
|
+
}
|
|
1586
|
+
getters.forEach((candidate, index) => {
|
|
1587
|
+
const field = declaration.fields[index];
|
|
1588
|
+
if (candidate.kind != "method")
|
|
1589
|
+
return unsupportedSyntax("php", "noncanonical generic record getter", nodeLocation(candidate, filename, source));
|
|
1590
|
+
const getter = /** @type {import("php-parser").Method} */ (candidate);
|
|
1591
|
+
const name = typeof getter.name == "string" ? getter.name : getter.name.name;
|
|
1592
|
+
const statement = getter.body?.children[0];
|
|
1593
|
+
const returned = statement?.kind == "return" ? /** @type {import("php-parser").Return} */ (statement).expr : undefined;
|
|
1594
|
+
const lookup = returned?.kind == "propertylookup" ? /** @type {import("php-parser").PropertyLookup} */ (returned) : undefined;
|
|
1595
|
+
const receiver = lookup?.what.kind == "variable" ? /** @type {import("php-parser").Variable} */ (lookup.what) : undefined;
|
|
1596
|
+
const member = lookup?.offset.kind == "identifier" ? /** @type {import("php-parser").Identifier} */ (lookup.offset) : undefined;
|
|
1597
|
+
if (name != field.name || getter.visibility != "public" || getter.isStatic || getter.isAbstract || getter.isFinal ||
|
|
1598
|
+
Reflect.get(getter, "isReadonly") || getter.byref || getter.arguments.length || getter.attrGroups.length ||
|
|
1599
|
+
!getter.body || getter.body.children.length != 1 || receiver?.name != "this" || member?.name != field.name) {
|
|
1600
|
+
return unsupportedSyntax("php", "noncanonical generic record getter", nodeLocation(getter, filename, source));
|
|
1601
|
+
}
|
|
1602
|
+
const documented = functionDocumentedTypes(
|
|
1603
|
+
/** @type {import("php-parser").Function} */ ( /** @type {unknown} */(getter)), filename, source);
|
|
1604
|
+
if (documented.parameters.size || documented.typeParameters || !documented.returnType) {
|
|
1605
|
+
return unsupportedSyntax("php", "missing or invalid generic record getter type", nodeLocation(getter, filename, source));
|
|
1606
|
+
}
|
|
1607
|
+
const returnType = documentedValueType({ language: "php", location: documented.returnType.location,
|
|
1608
|
+
ownerLocation: nodeLocation(getter, filename, source), records: recordNames, source,
|
|
1609
|
+
sourceType: documented.returnType.sourceType, subject: `Record getter '${name}'`, typeParameters });
|
|
1610
|
+
const nativeType = phpTypeName(getter.type);
|
|
1611
|
+
if (!phpDocumentedNativeTypeMatches(nativeType, getter.nullable, returnType, recordNames) ||
|
|
1612
|
+
!sameValueType(returnType, field.type)) {
|
|
1613
|
+
return unsupportedSyntax("php", "generic record getter type mismatch", documented.returnType.location);
|
|
1614
|
+
}
|
|
1615
|
+
});
|
|
388
1616
|
}
|
|
389
1617
|
/**
|
|
390
1618
|
* Converts the existing PHP if/else terminal with restricted branch prefixes.
|
|
391
1619
|
* @param {import("php-parser").If} node - PHP if node.
|
|
392
|
-
* @param {Set<string>} visible - Enclosing visible names.
|
|
393
1620
|
* @param {string} filename - Source filename.
|
|
394
1621
|
* @param {string} source - Complete source.
|
|
1622
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
395
1623
|
* @returns {import("../semantic/types.js").IfStatement} Semantic branch.
|
|
396
1624
|
*/
|
|
397
|
-
function convertIf(node,
|
|
1625
|
+
function convertIf(node, filename, source, context) {
|
|
398
1626
|
const location = nodeLocation(node, filename, source);
|
|
399
1627
|
if (node.shortForm)
|
|
400
1628
|
return unsupportedSyntax("php", "alternative if syntax", location);
|
|
401
1629
|
if (node.body.kind != "block")
|
|
402
1630
|
return unsupportedSyntax("php", "if without block consequent", location);
|
|
403
|
-
|
|
1631
|
+
if (node.test.kind == "variable") {
|
|
1632
|
+
const tested = /** @type {import("php-parser").Variable} */ (node.test);
|
|
1633
|
+
if (typeof tested.name == "string" && context.bindings.get(tested.name)?.kind == "OptionalType") {
|
|
1634
|
+
return unsupportedSyntax("php", "optional truthiness condition", nodeLocation(tested, filename, source));
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
const condition = convertExpression(node.test, filename, source, context);
|
|
1638
|
+
const consequentContext = { ...context, bindings: new Map(context.bindings) };
|
|
1639
|
+
const alternateContext = { ...context, bindings: new Map(context.bindings) };
|
|
404
1640
|
let alternate;
|
|
405
1641
|
if (node.alternate) {
|
|
406
|
-
const alternateVisible = new Set(visible);
|
|
407
1642
|
if (node.alternate.kind == "block") {
|
|
408
|
-
alternate = convertBlock(/** @type {import("php-parser").Block} */ (node.alternate),
|
|
1643
|
+
alternate = convertBlock(/** @type {import("php-parser").Block} */ (node.alternate), filename, source, alternateContext);
|
|
409
1644
|
}
|
|
410
1645
|
else if (node.alternate.kind == "if") {
|
|
411
1646
|
const nested = /** @type {import("php-parser").If} */ (node.alternate);
|
|
412
1647
|
alternate = {
|
|
413
1648
|
kind: /** @type {const} */ ("Block"),
|
|
414
1649
|
location: nodeLocation(nested, filename, source),
|
|
415
|
-
statements: [convertIf(nested,
|
|
1650
|
+
statements: [convertIf(nested, filename, source, alternateContext)]
|
|
416
1651
|
};
|
|
417
1652
|
}
|
|
418
1653
|
else
|
|
@@ -420,54 +1655,164 @@ function convertIf(node, visible, filename, source) {
|
|
|
420
1655
|
}
|
|
421
1656
|
return {
|
|
422
1657
|
...(alternate ? { alternate } : {}),
|
|
423
|
-
condition
|
|
424
|
-
consequent: convertBlock(node.body,
|
|
1658
|
+
condition,
|
|
1659
|
+
consequent: convertBlock(node.body, filename, source, consequentContext),
|
|
425
1660
|
kind: "IfStatement",
|
|
426
1661
|
location
|
|
427
1662
|
};
|
|
428
1663
|
}
|
|
1664
|
+
/**
|
|
1665
|
+
* Converts exact braced PHP `while ($condition) { ... }` syntax.
|
|
1666
|
+
* @param {import("php-parser").While} node - PHP while node.
|
|
1667
|
+
* @param {string} filename - Source filename.
|
|
1668
|
+
* @param {string} source - Complete source.
|
|
1669
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
1670
|
+
* @returns {import("../semantic/types.js").WhileStatement} Semantic loop.
|
|
1671
|
+
*/
|
|
1672
|
+
function convertWhile(node, filename, source, context) {
|
|
1673
|
+
const location = nodeLocation(node, filename, source);
|
|
1674
|
+
if (node.shortForm)
|
|
1675
|
+
return unsupportedSyntax("php", "alternative while syntax", location);
|
|
1676
|
+
if (!node.body || node.body.kind != "block") {
|
|
1677
|
+
return unsupportedSyntax("php", "while without block body", node.body ? nodeLocation(node.body, filename, source) : location);
|
|
1678
|
+
}
|
|
1679
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
1680
|
+
return withParserRanges({
|
|
1681
|
+
body: convertBlock(/** @type {import("php-parser").Block} */ (node.body), filename, source, bodyContext),
|
|
1682
|
+
condition: convertExpression(node.test, filename, source, context, undefined, true),
|
|
1683
|
+
kind: /** @type {const} */ ("WhileStatement"),
|
|
1684
|
+
location
|
|
1685
|
+
}, { keyword: tokenLocation("while", node.loc?.start.offset ?? 0, node.test.loc?.start.offset ?? source.length, filename, source) });
|
|
1686
|
+
}
|
|
429
1687
|
/**
|
|
430
1688
|
* Converts a PHP echo entry point.
|
|
431
1689
|
* @param {import("php-parser").Echo} node - PHP echo node.
|
|
432
1690
|
* @param {string} filename - Source filename.
|
|
433
1691
|
* @param {string} source - Complete source.
|
|
1692
|
+
* @param {PhpConversionContext} context - Typed conversion context.
|
|
434
1693
|
* @returns {import("../semantic/types.js").PrintStatement} Print statement.
|
|
435
1694
|
*/
|
|
436
|
-
function convertPrint(node, filename, source) {
|
|
1695
|
+
function convertPrint(node, filename, source, context) {
|
|
437
1696
|
const location = nodeLocation(node, filename, source);
|
|
438
1697
|
if (node.expressions.length != 2 || node.expressions[1].kind != "name" ||
|
|
439
1698
|
/** @type {import("php-parser").Name} */ (node.expressions[1]).name != "PHP_EOL") {
|
|
440
1699
|
return unsupportedSyntax("php", "echo without one expression and PHP_EOL", location);
|
|
441
1700
|
}
|
|
442
|
-
return { expression: convertExpression(node.expressions[0], filename, source), kind: "PrintStatement", location };
|
|
1701
|
+
return { expression: convertExpression(node.expressions[0], filename, source, context), kind: "PrintStatement", location };
|
|
443
1702
|
}
|
|
444
1703
|
/**
|
|
445
1704
|
* Parses PHP into the shared semantic module.
|
|
446
1705
|
* @param {object} input - Parser input.
|
|
447
1706
|
* @param {string} input.filename - Source filename.
|
|
448
1707
|
* @param {string} input.source - Source text.
|
|
1708
|
+
* @param {readonly import("../semantic/types.js").EffectCapabilityDeclaration[]} [input.capabilities] - Compiler-authorized declarations.
|
|
1709
|
+
* @param {{isEntry: boolean, functions: Map<string, import("../semantic/types.js").FunctionDeclaration>, records: Map<string, import("../semantic/types.js").RecordDeclaration>, errors?: Map<string, import("../semantic/types.js").ErrorDeclaration>}} [input.program] - Resolved program imports and entry role.
|
|
449
1710
|
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
450
1711
|
*/
|
|
451
|
-
export function parsePhp({ filename, source }) {
|
|
1712
|
+
export function parsePhp({ capabilities = [], filename, source, program: programContext }) {
|
|
452
1713
|
const program = parsePhpProgram(filename, source);
|
|
453
1714
|
validateDeclareNodes(program.children, filename, source);
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
1715
|
+
let body = task034PhpBody(program.children, capabilities, filename, source);
|
|
1716
|
+
if (programContext) {
|
|
1717
|
+
inspectPhpModule({ filename, source });
|
|
1718
|
+
const namespace = /** @type {import("php-parser").Namespace} */ (body.find((node) => node.kind == "namespace"));
|
|
1719
|
+
body = namespace.children.filter((node) => node.kind != "usegroup" && !isPhpRequireOnce(node));
|
|
1720
|
+
}
|
|
1721
|
+
const classNodes = /** @type {import("php-parser").Class[]} */ (body.filter((node) => node.kind == "class"));
|
|
1722
|
+
const errorNodes = classNodes.filter((node) => node.extends?.kind == "name" &&
|
|
1723
|
+
["RuntimeException", "\\RuntimeException"].includes(node.extends.name));
|
|
1724
|
+
const referenceClassNodes = classNodes.filter((node) => !errorNodes.includes(node) &&
|
|
1725
|
+
node.body.some((member) => member.kind == "propertystatement"));
|
|
1726
|
+
const recordNodes = classNodes.filter((node) => !errorNodes.includes(node) && !referenceClassNodes.includes(node));
|
|
1727
|
+
const errorDeclarations = errorNodes.map((node, index) => ({
|
|
1728
|
+
id: `error:${index}`,
|
|
1729
|
+
kind: /** @type {const} */ ("ErrorDeclaration"),
|
|
1730
|
+
location: nodeLocation(node, filename, source),
|
|
1731
|
+
name: typeof node.name == "string" ? node.name : node.name.name
|
|
1732
|
+
}));
|
|
1733
|
+
const recordDeclarations = recordNodes.map((node, index) => {
|
|
1734
|
+
const id = `record:${index}`;
|
|
1735
|
+
const typeParameters = classDocumentedTypeParameters(node, id, filename, source);
|
|
1736
|
+
return {
|
|
1737
|
+
fields: [],
|
|
1738
|
+
id,
|
|
1739
|
+
kind: /** @type {const} */ ("RecordDeclaration"),
|
|
1740
|
+
location: nodeLocation(node, filename, source),
|
|
1741
|
+
name: typeof node.name == "string" ? node.name : node.name.name,
|
|
1742
|
+
...(typeParameters ? { typeParameters } : {})
|
|
1743
|
+
};
|
|
1744
|
+
});
|
|
1745
|
+
const classDeclarations = referenceClassNodes.map((node, index) => ({
|
|
1746
|
+
constructor: /** @type {import("../semantic/types.js").ConstructorDeclaration} */ ({}),
|
|
1747
|
+
fields: [], id: `class:${index}`, kind: /** @type {const} */ ("ClassDeclaration"),
|
|
1748
|
+
location: nodeLocation(node, filename, source), methods: [],
|
|
1749
|
+
name: typeof node.name == "string" ? node.name : node.name.name
|
|
1750
|
+
}));
|
|
1751
|
+
const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} */ (new Map(programContext?.records ?? []));
|
|
1752
|
+
for (const resource of capabilities.flatMap(({ resources }) => resources))
|
|
1753
|
+
recordNames.set(resource.name, resource);
|
|
1754
|
+
const errorNames = new Map(programContext?.errors ?? []);
|
|
1755
|
+
for (const failure of capabilities.flatMap(({ failures }) => failures)) {
|
|
1756
|
+
errorNames.set(failure.name, /** @type {import("../semantic/types.js").ErrorDeclaration} */ ( /** @type {unknown} */(failure)));
|
|
1757
|
+
}
|
|
1758
|
+
for (const declaration of errorDeclarations)
|
|
1759
|
+
errorNames.set(declaration.name, declaration);
|
|
1760
|
+
const errorsById = new Map([...errorNames.values()].map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
|
|
1761
|
+
const errors = errorNodes.map((node, index) => convertPhpError(node, errorDeclarations[index], filename, source));
|
|
1762
|
+
for (const declaration of recordDeclarations)
|
|
1763
|
+
recordNames.set(declaration.name, declaration);
|
|
1764
|
+
for (const declaration of classDeclarations)
|
|
1765
|
+
recordNames.set(declaration.name, declaration);
|
|
1766
|
+
const recordsById = new Map([...recordNames.values()]
|
|
1767
|
+
.filter((declaration) => declaration.kind == "RecordDeclaration")
|
|
1768
|
+
.map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
|
|
1769
|
+
const classesById = new Map(classDeclarations.map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
|
|
1770
|
+
const records = recordNodes.map((node, index) => convertPhpRecord(node, recordDeclarations[index],
|
|
1771
|
+
/** @type {Map<string, import("../semantic/types.js").RecordDeclaration>} */ ( /** @type {unknown} */(recordNames)), filename, source));
|
|
1772
|
+
const functionNodes = /** @type {import("php-parser").Function[]} */ (body.filter((node) => node.kind == "function"));
|
|
1773
|
+
const signatures = functionNodes.map((node, index) => convertFunctionSignature(node, filename, source, recordNames, `function:${index}`));
|
|
1774
|
+
const functionSignatures = new Map([...capabilityFunctionSignatures(capabilities, moduleLocation(filename, source)),
|
|
1775
|
+
...(programContext?.functions ?? [])].map(([localName, declaration]) => [localName, {
|
|
1776
|
+
location: declaration.location,
|
|
1777
|
+
name: localName,
|
|
1778
|
+
nameLocation: declaration.location,
|
|
1779
|
+
parameters: declaration.parameters,
|
|
1780
|
+
returnType: declaration.returnType,
|
|
1781
|
+
...(declaration.typeParameters ? { typeParameters: declaration.typeParameters } : {})
|
|
1782
|
+
}]));
|
|
1783
|
+
for (const signature of signatures)
|
|
1784
|
+
functionSignatures.set(signature.name, signature);
|
|
1785
|
+
const classes = referenceClassNodes.map((node, index) => convertPhpReferenceClass(node, classDeclarations[index], recordNames, recordsById, classesById, functionSignatures, errorNames, errorsById, filename, source));
|
|
1786
|
+
const functions = functionNodes.map((node, index) => convertFunction(node, signatures[index], functionSignatures, recordNames, recordsById, classesById, errorNames, errorsById, filename, source));
|
|
1787
|
+
const executableNodes = body.filter((node) => !["class", "function", "declare", "noop"].includes(node.kind));
|
|
457
1788
|
const location = moduleLocation(filename, source);
|
|
458
|
-
if (
|
|
459
|
-
return unsupportedSyntax("php", "
|
|
1789
|
+
if (programContext && !programContext.isEntry && executableNodes.length > 0) {
|
|
1790
|
+
return unsupportedSyntax("php", "top-level side effect outside the selected entry module", nodeLocation(executableNodes[0], filename, source));
|
|
1791
|
+
}
|
|
460
1792
|
const first = executableNodes[0];
|
|
461
1793
|
const last = executableNodes.at(-1) ?? first;
|
|
462
1794
|
const entryLocation = first
|
|
463
1795
|
? locationFromOffsets(filename, source, first.loc?.start.offset ?? 0, last?.loc?.end.offset ?? source.length)
|
|
464
1796
|
: location;
|
|
465
|
-
const
|
|
1797
|
+
const entryContext = {
|
|
1798
|
+
bindings: new Map(),
|
|
1799
|
+
classes: classesById,
|
|
1800
|
+
errorNames,
|
|
1801
|
+
errors: errorsById,
|
|
1802
|
+
functions: functionSignatures,
|
|
1803
|
+
orderedMapDeclarations: orderedMapDeclarationsForPhp(executableNodes),
|
|
1804
|
+
recordNames,
|
|
1805
|
+
records: recordsById,
|
|
1806
|
+
returnType: undefined
|
|
1807
|
+
};
|
|
466
1808
|
const entryBlock = {
|
|
467
1809
|
kind: /** @type {const} */ ("Block"),
|
|
468
1810
|
location: entryLocation,
|
|
469
|
-
statements: executableNodes.map((node) => convertStatement(node,
|
|
1811
|
+
statements: executableNodes.map((node) => convertStatement(node, filename, source, entryContext))
|
|
470
1812
|
};
|
|
1813
|
+
if (!programContext && functions.length == 0 && capabilities.length == 0 && !blockReferencesProtectedEntry(entryBlock)) {
|
|
1814
|
+
return unsupportedSyntax("php", "module without a function", location);
|
|
1815
|
+
}
|
|
471
1816
|
return {
|
|
472
1817
|
entryPoint: {
|
|
473
1818
|
body: entryBlock,
|
|
@@ -476,9 +1821,142 @@ export function parsePhp({ filename, source }) {
|
|
|
476
1821
|
},
|
|
477
1822
|
functions,
|
|
478
1823
|
kind: "Module",
|
|
479
|
-
location
|
|
1824
|
+
location,
|
|
1825
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
1826
|
+
...(classes.length > 0 ? { classes } : {}),
|
|
1827
|
+
...(records.length > 0 ? { records } : {})
|
|
480
1828
|
};
|
|
481
1829
|
}
|
|
1830
|
+
/**
|
|
1831
|
+
* Removes exact protected PHP probe support before portable conversion.
|
|
1832
|
+
* @param {import("php-parser").Statement[]} body - Parsed top-level statements.
|
|
1833
|
+
* @param {readonly import("../semantic/types.js").EffectCapabilityDeclaration[]} capabilities - Authorized declarations.
|
|
1834
|
+
* @param {string} filename - Source filename.
|
|
1835
|
+
* @param {string} source - Complete source.
|
|
1836
|
+
* @returns {import("php-parser").Statement[]} Portable statements.
|
|
1837
|
+
*/
|
|
1838
|
+
function task034PhpBody(body, capabilities, filename, source) {
|
|
1839
|
+
if (!isTask034ResourceProbe(capabilities))
|
|
1840
|
+
return body;
|
|
1841
|
+
const start = body.findIndex((node) => node.leadingComments?.some(({ value }) => value == "/* semantifold-task034-support */"));
|
|
1842
|
+
if (start < 0)
|
|
1843
|
+
return body;
|
|
1844
|
+
if (!hasExactEffectSupport(source, "php")) {
|
|
1845
|
+
return unsupportedSyntax("php", "malformed protected Task 034 support", nodeLocation(body[start], filename, source));
|
|
1846
|
+
}
|
|
1847
|
+
const expected = [
|
|
1848
|
+
["class", "ProbeOperationFailure"], ["class", "ProbeAcquireFailure"], ["class", "ProbeReadFailure"],
|
|
1849
|
+
["class", "ProbeCloseFailure"], ["class", "ProbeResourceClosed"], ["class", "ProbeResource"],
|
|
1850
|
+
["expressionstatement", undefined], ["function", "probeEffect"], ["function", "probeAcquire"],
|
|
1851
|
+
["function", "probeRead"], ["function", "probeClose"], ["function", "probeTrace"]
|
|
1852
|
+
];
|
|
1853
|
+
const matches = expected.every(([kind, name], index) => {
|
|
1854
|
+
const node = body[start + index];
|
|
1855
|
+
const rawName = node ? Reflect.get(node, "name") : undefined;
|
|
1856
|
+
const actualName = typeof rawName == "string" ? rawName : rawName && typeof rawName == "object" ? Reflect.get(rawName, "name") : undefined;
|
|
1857
|
+
return node?.kind == kind && actualName == name;
|
|
1858
|
+
});
|
|
1859
|
+
const next = body[start + expected.length];
|
|
1860
|
+
if (!matches || next && !next.leadingComments?.some(({ value }) => value == "/* semantifold-task034-support-end */")) {
|
|
1861
|
+
return unsupportedSyntax("php", "malformed protected Task 034 support", nodeLocation(body[start], filename, source));
|
|
1862
|
+
}
|
|
1863
|
+
return [...body.slice(0, start), ...body.slice(start + expected.length)];
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Reads the canonical parser-owned PHP namespace, use bindings, and literal require_once edges.
|
|
1867
|
+
* @param {object} input - Parser input.
|
|
1868
|
+
* @param {string} input.filename - Source filename.
|
|
1869
|
+
* @param {string} input.source - Source text.
|
|
1870
|
+
* @returns {{bindings: {importedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, nativeName: string, symbolKind: import("../semantic/types.js").SemanticDeclarationKind, typeOnly: false}[], imports: {importedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, namespace: true, pathLocation: import("../semantic/types.js").SourceLocation, specifier: string, typeOnly: false}[], exports: {exportedName: string, localName: string, location: import("../semantic/types.js").SourceLocation, typeOnly: false}[], nativeName: string}} Parser-owned PHP module header.
|
|
1871
|
+
*/
|
|
1872
|
+
export function inspectPhpModule({ filename, source }) {
|
|
1873
|
+
const program = parsePhpProgram(filename, source);
|
|
1874
|
+
validateDeclareNodes(program.children, filename, source);
|
|
1875
|
+
const namespaces = program.children.filter((node) => node.kind == "namespace");
|
|
1876
|
+
const invalidOuter = program.children.find((node) => !["declare", "namespace", "noop"].includes(node.kind));
|
|
1877
|
+
const namespace = /** @type {import("php-parser").Namespace | undefined} */ (namespaces[0]);
|
|
1878
|
+
if (!namespace || namespaces.length != 1 || namespace.withBrackets || typeof namespace.name != "string" || invalidOuter) {
|
|
1879
|
+
return unsupportedSyntax("php", "one canonical unbracketed namespace", nodeLocation(invalidOuter ?? namespaces[1] ?? namespace ?? program, filename, source));
|
|
1880
|
+
}
|
|
1881
|
+
const bindings = [];
|
|
1882
|
+
for (const node of namespace.children.filter((child) => child.kind == "usegroup")) {
|
|
1883
|
+
const group = /** @type {import("php-parser").UseGroup} */ (node);
|
|
1884
|
+
if (group.name !== null || ![null, "function"].includes(group.type) || group.items.length == 0) {
|
|
1885
|
+
return unsupportedSyntax("php", "grouped, constant, or empty use declaration", nodeLocation(group, filename, source));
|
|
1886
|
+
}
|
|
1887
|
+
for (const item of group.items) {
|
|
1888
|
+
if (item.type !== null || typeof item.name != "string" || !item.name.includes("\\")) {
|
|
1889
|
+
return unsupportedSyntax("php", "grouped or unqualified use item", nodeLocation(item, filename, source));
|
|
1890
|
+
}
|
|
1891
|
+
const importedName = item.name.split("\\").at(-1);
|
|
1892
|
+
const alias = item.alias;
|
|
1893
|
+
if (!importedName || alias && alias.kind != "identifier") {
|
|
1894
|
+
return unsupportedSyntax("php", "invalid use alias", nodeLocation(item, filename, source));
|
|
1895
|
+
}
|
|
1896
|
+
bindings.push({
|
|
1897
|
+
importedName,
|
|
1898
|
+
localName: alias ? alias.name : importedName,
|
|
1899
|
+
location: nodeLocation(item, filename, source),
|
|
1900
|
+
nativeName: item.name,
|
|
1901
|
+
symbolKind: /** @type {import("../semantic/types.js").SemanticDeclarationKind} */ (group.type == "function" ? "function" : "record"),
|
|
1902
|
+
typeOnly: /** @type {const} */ (false)
|
|
1903
|
+
});
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1906
|
+
const imports = namespace.children.filter(isPhpIncludeStatement).map((node) => {
|
|
1907
|
+
if (!isPhpRequireOnce(node)) {
|
|
1908
|
+
return unsupportedSyntax("php", "include/require outside literal require_once __DIR__ profile", nodeLocation(node, filename, source));
|
|
1909
|
+
}
|
|
1910
|
+
const statement = /** @type {import("php-parser").ExpressionStatement} */ (node);
|
|
1911
|
+
const include = /** @type {import("php-parser").Include} */ (statement.expression);
|
|
1912
|
+
const target = /** @type {import("php-parser").Bin} */ (include.target);
|
|
1913
|
+
const path = /** @type {import("php-parser").String} */ (target.right);
|
|
1914
|
+
if (!path.value.startsWith("/") || path.value.includes("\0")) {
|
|
1915
|
+
return unsupportedSyntax("php", "unsafe require_once path", nodeLocation(path, filename, source));
|
|
1916
|
+
}
|
|
1917
|
+
return {
|
|
1918
|
+
importedName: "*",
|
|
1919
|
+
localName: "",
|
|
1920
|
+
location: nodeLocation(node, filename, source),
|
|
1921
|
+
namespace: /** @type {const} */ (true),
|
|
1922
|
+
pathLocation: nodeLocation(path, filename, source),
|
|
1923
|
+
specifier: `.${path.value}`,
|
|
1924
|
+
typeOnly: /** @type {const} */ (false)
|
|
1925
|
+
};
|
|
1926
|
+
});
|
|
1927
|
+
const exports = namespace.children.flatMap((node) => {
|
|
1928
|
+
if (node.kind != "class" && node.kind != "function")
|
|
1929
|
+
return [];
|
|
1930
|
+
const declaration = /** @type {import("php-parser").Class | import("php-parser").Function} */ (node);
|
|
1931
|
+
const name = typeof declaration.name == "string" ? declaration.name : declaration.name.name;
|
|
1932
|
+
return [{ exportedName: name, localName: name, location: nodeLocation(node, filename, source), typeOnly: /** @type {const} */ (false) }];
|
|
1933
|
+
});
|
|
1934
|
+
return { bindings, exports, imports, nativeName: namespace.name };
|
|
1935
|
+
}
|
|
1936
|
+
/**
|
|
1937
|
+
* Reports whether a PHP statement is any include/require expression.
|
|
1938
|
+
* @param {import("php-parser").Node} node - Candidate statement.
|
|
1939
|
+
* @returns {boolean} Whether the node is an include expression statement.
|
|
1940
|
+
*/
|
|
1941
|
+
function isPhpIncludeStatement(node) {
|
|
1942
|
+
return node.kind == "expressionstatement" &&
|
|
1943
|
+
/** @type {import("php-parser").ExpressionStatement} */ (node).expression.kind == "include";
|
|
1944
|
+
}
|
|
1945
|
+
/**
|
|
1946
|
+
* Reports whether a PHP statement is the canonical literal project load edge.
|
|
1947
|
+
* @param {import("php-parser").Node} node - Candidate statement.
|
|
1948
|
+
* @returns {boolean} Whether the node is a supported require-once statement.
|
|
1949
|
+
*/
|
|
1950
|
+
function isPhpRequireOnce(node) {
|
|
1951
|
+
if (!isPhpIncludeStatement(node))
|
|
1952
|
+
return false;
|
|
1953
|
+
const statement = /** @type {import("php-parser").ExpressionStatement} */ (node);
|
|
1954
|
+
const include = /** @type {import("php-parser").Include} */ (statement.expression);
|
|
1955
|
+
const target = include.target.kind == "bin" ? /** @type {import("php-parser").Bin} */ (include.target) : undefined;
|
|
1956
|
+
const left = target?.left.kind == "magic" ? /** @type {import("php-parser").Magic} */ (target.left) : undefined;
|
|
1957
|
+
return include.once && include.require && target?.type == "." &&
|
|
1958
|
+
left?.value == "__DIR__" && target.right.kind == "string";
|
|
1959
|
+
}
|
|
482
1960
|
/**
|
|
483
1961
|
* Accepts only an optional single `declare(strict_types=1)` directive.
|
|
484
1962
|
* @param {import("php-parser").Node[]} nodes - Top-level PHP nodes.
|
|
@@ -517,7 +1995,36 @@ function parsePhpProgram(filename, source) {
|
|
|
517
1995
|
return parser.parseCode(source, filename);
|
|
518
1996
|
}
|
|
519
1997
|
catch (error) {
|
|
520
|
-
return parseFailure("php", error);
|
|
1998
|
+
return parseFailure("php", error, phpParserFailureLocation(error, filename, source));
|
|
1999
|
+
}
|
|
2000
|
+
}
|
|
2001
|
+
/**
|
|
2002
|
+
* Normalizes php-parser's one-based line and zero-based column when present.
|
|
2003
|
+
* A module range remains the deterministic fallback for opaque parser errors.
|
|
2004
|
+
* @param {unknown} error - Native parser error.
|
|
2005
|
+
* @param {string} filename - Requested source filename.
|
|
2006
|
+
* @param {string} source - Complete source.
|
|
2007
|
+
* @returns {import("../semantic/types.js").SourceLocation} Failure range.
|
|
2008
|
+
*/
|
|
2009
|
+
function phpParserFailureLocation(error, filename, source) {
|
|
2010
|
+
if (!error || typeof error != "object")
|
|
2011
|
+
return moduleLocation(filename, source);
|
|
2012
|
+
const line = Reflect.get(error, "lineNumber");
|
|
2013
|
+
const column = Reflect.get(error, "columnNumber");
|
|
2014
|
+
if (typeof line != "number" || !Number.isSafeInteger(line) || line < 1 ||
|
|
2015
|
+
typeof column != "number" || !Number.isSafeInteger(column) || column < 0) {
|
|
2016
|
+
return moduleLocation(filename, source);
|
|
2017
|
+
}
|
|
2018
|
+
let lineStart = 0;
|
|
2019
|
+
for (let current = 1; current < line; current++) {
|
|
2020
|
+
const newline = source.indexOf("\n", lineStart);
|
|
2021
|
+
if (newline < 0)
|
|
2022
|
+
return moduleLocation(filename, source);
|
|
2023
|
+
lineStart = newline + 1;
|
|
521
2024
|
}
|
|
2025
|
+
const lineEnd = source.indexOf("\n", lineStart);
|
|
2026
|
+
const boundedEnd = lineEnd < 0 ? source.length : lineEnd;
|
|
2027
|
+
const offset = Math.min(lineStart + column, boundedEnd);
|
|
2028
|
+
return locationFromOffsets(filename, source, offset, Math.min(offset + 1, source.length));
|
|
522
2029
|
}
|
|
523
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9waHAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQTtBQUNsQyxPQUFPLEVBQUMsS0FBSyxJQUFJLFlBQVksRUFBQyxNQUFNLGdCQUFnQixDQUFBO0FBQ3BELE9BQU8sRUFBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDN0UsT0FBTyxFQUFDLG1CQUFtQixFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzNFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFBO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJCQUEyQixDQUFBO0FBQzFELE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQzVELE9BQU8sRUFBQyx1QkFBdUIsRUFBQyxNQUFNLGNBQWMsQ0FBQTtBQUNwRCxNQUFNLE1BQU0sR0FBRyxJQUFJLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDbEMsR0FBRyxFQUFFLEVBQUMsYUFBYSxFQUFFLElBQUksRUFBQztJQUMxQixNQUFNLEVBQUUsRUFBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUM7Q0FDbEQsQ0FBQyxDQUFBO0FBQ0YsaUNBQWlDO0FBQ2pDLElBQUksaUJBQWlCLENBQUE7QUFDckIsMkRBQTJEO0FBQzNELElBQUksaUJBQWlCLEdBQUcsRUFBRSxDQUFBO0FBQzFCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDbEMsQ0FBQyxHQUFHLEVBQUUsUUFBUSxDQUFDO0lBQ2YsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQztJQUNqQixDQUFDLElBQUksRUFBRSxL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QUMsQ0FBQyxDQUFBO0lBQzVDLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxJQUFJLElBQUksRUFBRSxDQUFBO0lBQzlCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksS0FBSyxDQUFDLENBQUE7SUFDeEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSx1QkFBdUIsQ0FBQyxDQUFBO0lBQzFFLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRXJELElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDO1FBQUUsT0FBTyxTQUFTLENBQUE7SUFFcEUsTUFBTSxhQUFhLEdBQUcsU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLElBQUksU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFBO0lBQ2hILE1BQU0sY0FBYyxHQUFHLFNBQVMsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxJQUFJLElBQUksRUFBRSxJQUFJLEdBQUcsQ0FBQyxXQUFXLElBQUksRUFBRSxDQUFDLENBQUE7SUFDbkksTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxLQUFLLElBQUksR0FBRyxDQUFDLEdBQUcsSUFBSSx1QkFBdUIsQ0FBQyxDQUFBO0lBRTdG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S0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFBO0lBQ25DLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBQaHBQYXJzZXIgZnJvbSBcInBocC1wYXJzZXJcIlxuaW1wb3J0IHtwYXJzZSBhcyBwYXJzZUNvbW1lbnR9IGZyb20gXCJjb21tZW50LXBhcnNlclwiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBwYXJzZUZhaWx1cmUsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2xvY2F0aW9uRnJvbU9mZnNldHMsIG1vZHVsZUxvY2F0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvbG9jYXRpb24uanNcIlxuaW1wb3J0IHt3aXRoQWRhcHRlZE9wZXJhdGlvbn0gZnJvbSBcIi4uL3NlbWFudGljL29wZXJhdG9ycy5qc1wiXG5pbXBvcnQge3dpdGhQYXJzZXJSYW5nZXN9IGZyb20gXCIuLi9zZW1hbnRpYy9wcm92ZW5hbmNlLmpzXCJcbmltcG9ydCB7aGFzT25seVVuaWNvZGVTY2FsYXJzfSBmcm9tIFwiLi4vc2VtYW50aWMvc2NhbGFycy5qc1wiXG5pbXBvcnQge3JlcXVpcmVTb3VyY2VTY2FsYXJUeXBlfSBmcm9tIFwiLi9zY2FsYXJzLmpzXCJcbmNvbnN0IHBhcnNlciA9IG5ldyBQaHBQYXJzZXIuRW5naW5lKHtcbiAgYXN0OiB7d2l0aFBvc2l0aW9uczogdHJ1ZX0sXG4gIHBhcnNlcjoge2V4dHJhY3REb2M6IHRydWUsIHN1cHByZXNzRXJyb3JzOiBmYWxzZX1cbn0pXG4vKiogQHR5cGUge3N0cmluZyB8IHVuZGVmaW5lZH0gKi9cbmxldCBjYWNoZWRUb2tlblNvdXJjZVxuLyoqIEB0eXBlIHt7ZW5kOiBudW1iZXIsIHN0YXJ0OiBudW1iZXIsIHRleHQ6IHN0cmluZ31bXX0gKi9cbmxldCBjYWNoZWRUb2tlblJhbmdlcyA9IFtdXG5jb25zdCBwaHBCaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJQaHBBZGRcIl0sXG4gIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wiKlwiLCBcIk11bHRpcGx5XCJdLFxuICBbXCImJlwiLCBcIkFuZFwiXSxcbiAgW1wifHxcIiwgXCJPclwiXSxcbiAgW1wiPT09XCIsIFwiRXF1YWxcIl0sXG4gIFtcIiE9PVwiLCBcIk5vdEVxdWFsXCJdLFxuICBbXCI8XCIsIFwiTGVzc1RoYW5cIl0sXG4gIFtcIjw9XCIsIFwiTGVzc1RoYW5PckVxdWFsXCJdLFxuICBbXCI+XCIsIFwiR3JlYXRlclRoYW5cIl0sXG4gIFtcIj49XCIsIFwiR3JlYXRlclRoYW5PckVxdWFsXCJdLFxuICBbXCIuXCIsIFwiU3RyaW5nQ29uY2F0XCJdXG5dKVxuXG4vKipcbiAqIFJldHVybnMgYSBub3JtYWxpemVkIFBIUCBub2RlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgcGFyc2VyIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBTb3VyY2UgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICghbm9kZS5sb2MpIHRocm93IG5ldyBFcnJvcihgUEhQIHBhcnNlciBvbWl0dGVkIHNvdXJjZSBsb2NhdGlvbiBmb3IgJHtub2RlLmtpbmR9LmApXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgbm9kZS5sb2Muc3RhcnQub2Zmc2V0LCBub2RlLmxvYy5lbmQub2Zmc2V0KVxufVxuXG4vKipcbiAqIExvY2F0ZXMgYSBjb21tZW50LXBhcnNlciB0b2tlbiBpbnNpZGUgYSBQSFAgcGFyc2VyLW93bmVkIGRvYyBjb21tZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNvbW1lbnRCbG9ja30gY29tbWVudCAtIFBIUCBkb2MgY29tbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiY29tbWVudC1wYXJzZXJcIikuU3BlY30gdGFnIC0gUGFyc2VkIGRvYyB0YWcuXG4gKiBAcGFyYW0ge1wibmFtZVwiIHwgXCJ0eXBlXCJ9IGZpZWxkIC0gVG9rZW4gZmllbGQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBFeGFjdCB0b2tlbiBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHRhZywgZmllbGQsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbGluZSA9IHRhZy5zb3VyY2VbMF1cblxuICBpZiAoIWNvbW1lbnQubG9jIHx8ICFsaW5lKSB0aHJvdyBuZXcgRXJyb3IoYENvbW1lbnQgcGFyc2VyIG9taXR0ZWQgdGhlIEAke3RhZy50YWd9IHNvdXJjZSB0b2tlbi5gKVxuXG4gIGxldCBsaW5lU3RhcnQgPSBjb21tZW50LmxvYy5zdGFydC5vZmZzZXRcblxuICBmb3IgKGxldCBsaW5lTnVtYmVyID0gMDsgbGluZU51bWJlciA8IGxpbmUubnVtYmVyOyBsaW5lTnVtYmVyKyspIHtcbiAgICB3aGlsZSAobGluZVN0YXJ0IDwgc291cmNlLmxlbmd0aCAmJiBzb3VyY2VbbGluZVN0YXJ0XSAhPSBcIlxcclwiICYmIHNvdXJjZVtsaW5lU3RhcnRdICE9IFwiXFxuXCIpIGxpbmVTdGFydCsrXG4gICAgaWYgKHNvdXJjZVtsaW5lU3RhcnRdID09IFwiXFxyXCIgJiYgc291cmNlW2xpbmVTdGFydCArIDFdID09IFwiXFxuXCIpIGxpbmVTdGFydCArPSAyXG4gICAgZWxzZSBsaW5lU3RhcnQrK1xuICB9XG5cbiAgY29uc3Qgb3JkZXJlZEZpZWxkcyA9IFtcInN0YXJ0XCIsIFwiZGVsaW1pdGVyXCIsIFwicG9zdERlbGltaXRlclwiLCBcInRhZ1wiLCBcInBvc3RUYWdcIiwgXCJuYW1lXCIsIFwicG9zdE5hbWVcIiwgXCJ0eXBlXCJdXG4gIGNvbnN0IGZpZWxkSW5kZXggPSBvcmRlcmVkRmllbGRzLmluZGV4T2YoZmllbGQpXG4gIGNvbnN0IHN0YXJ0ID0gbGluZVN0YXJ0ICsgb3JkZXJlZEZpZWxkcy5zbGljZSgwLCBmaWVsZEluZGV4KS5yZWR1Y2UoKGxlbmd0aCwga2V5KSA9PlxuICAgIGxlbmd0aCArIGxpbmUudG9rZW5zWy8qKiBAdHlwZSB7a2V5b2YgdHlwZW9mIGxpbmUudG9rZW5zfSAqLyAoa2V5KV0ubGVuZ3RoLCAwKVxuICBjb25zdCB2YWx1ZSA9IGxpbmUudG9rZW5zW2ZpZWxkXVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIHN0YXJ0LCBzdGFydCArIHZhbHVlLmxlbmd0aClcbn1cblxuLyoqXG4gKiBGaW5kcyBvbmUgcGFyc2VyIHRva2VuIGJldHdlZW4gcGFyc2VyLW93bmVkIG5vZGUgYm91bmRhcmllcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0b2tlblRleHQgLSBFeGFjdCB0b2tlbiB0ZXh0LlxuICogQHBhcmFtIHtudW1iZXJ9IHN0YXJ0T2Zmc2V0IC0gSW5jbHVzaXZlIHNlYXJjaCBib3VuZGFyeS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmRPZmZzZXQgLSBFeGNsdXNpdmUgc2VhcmNoIGJvdW5kYXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gVG9rZW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHRva2VuTG9jYXRpb24odG9rZW5UZXh0LCBzdGFydE9mZnNldCwgZW5kT2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmIChjYWNoZWRUb2tlblNvdXJjZSAhPSBzb3VyY2UpIHtcbiAgICBsZXQgb2Zmc2V0ID0gMFxuXG4gICAgY2FjaGVkVG9rZW5SYW5nZXMgPSBwYXJzZXIudG9rZW5HZXRBbGwoc291cmNlKS5tYXAoKHRva2VuKSA9PiB7XG4gICAgICBjb25zdCB0ZXh0ID0gdHlwZW9mIHRva2VuID09IFwic3RyaW5nXCIgPyB0b2tlbiA6IHRva2VuWzFdXG4gICAgICBjb25zdCByYW5nZSA9IHtlbmQ6IG9mZnNldCArIHRleHQubGVuZ3RoLCBzdGFydDogb2Zmc2V0LCB0ZXh0fVxuXG4gICAgICBvZmZzZXQgPSByYW5nZS5lbmRcblxuICAgICAgcmV0dXJuIHJhbmdlXG4gICAgfSlcbiAgICBjYWNoZWRUb2tlblNvdXJjZSA9IHNvdXJjZVxuICB9XG5cbiAgY29uc3QgdG9rZW4gPSBjYWNoZWRUb2tlblJhbmdlcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS50ZXh0ID09IHRva2VuVGV4dCAmJiBjYW5kaWRhdGUuc3RhcnQgPj0gc3RhcnRPZmZzZXQgJiZcbiAgICBjYW5kaWRhdGUuZW5kIDw9IGVuZE9mZnNldClcblxuICBpZiAodG9rZW4pIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIHRva2VuLnN0YXJ0LCB0b2tlbi5lbmQpXG5cbiAgdGhyb3cgbmV3IEVycm9yKGBQSFAgcGFyc2VyIG9taXR0ZWQgdG9rZW4gJyR7dG9rZW5UZXh0fScgYmV0d2VlbiAke3N0YXJ0T2Zmc2V0fSBhbmQgJHtlbmRPZmZzZXR9LmApXG59XG5cbi8qKlxuICogQ29udmVydHMgYSBzdXBwb3J0ZWQgUEhQIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBIUCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInZhcmlhYmxlXCIpIHtcbiAgICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKG5vZGUpXG5cbiAgICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyB2YXJpYWJsZVwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IHZhcmlhYmxlLm5hbWV9LCB7bmFtZTogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcIm51bWJlclwiKSB7XG4gICAgY29uc3QgbGl0ZXJhbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OdW1iZXJ9ICovIChub2RlKVxuICAgIGNvbnN0IHZhbHVlID0gTnVtYmVyKGxpdGVyYWwudmFsdWUpXG5cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uLXNhZmUgaW50ZWdlciBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkludGVnZXJMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImJvb2xlYW5cIikge1xuICAgIGNvbnN0IGxpdGVyYWwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQm9vbGVhbn0gKi8gKG5vZGUpXG5cbiAgICBpZiAodHlwZW9mIGxpdGVyYWwudmFsdWUgIT0gXCJib29sZWFuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImludmFsaWQgYm9vbGVhbiBsaXRlcmFsIHZhbHVlXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJvb2xlYW5MaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IGxpdGVyYWwudmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgY29uc3QgbGl0ZXJhbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovIChub2RlKVxuXG4gICAgaWYgKHR5cGVvZiBsaXRlcmFsLnJhdyA9PSBcInN0cmluZ1wiICYmIGxpdGVyYWwucmF3LnN0YXJ0c1dpdGgoXCI8PDxcIikpIHtcbiAgICAgIGNvbnN0IGRldGFpbCA9IGxpdGVyYWwucmF3LnN0YXJ0c1dpdGgoXCI8PDwnXCIpID8gXCJub3dkb2Mgc3RyaW5nXCIgOiBcImhlcmVkb2Mgc3RyaW5nXCJcblxuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGRldGFpbCwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICh0eXBlb2YgbGl0ZXJhbC5yYXcgPT0gXCJzdHJpbmdcIiAmJiBbXCJiXFxcIlwiLCBcIkJcXFwiXCIsIFwiYidcIiwgXCJCJ1wiXS5zb21lKChwcmVmaXgpID0+IGxpdGVyYWwucmF3LnN0YXJ0c1dpdGgocHJlZml4KSkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImJpbmFyeSBzdHJpbmcgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBsaXRlcmFsLnZhbHVlICE9IFwic3RyaW5nXCIgfHwgIWhhc09ubHlVbmljb2RlU2NhbGFycyhsaXRlcmFsLnZhbHVlKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaW52YWxpZCBVbmljb2RlIHN0cmluZyBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IGxpdGVyYWwudmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImVuY2Fwc2VkXCIpIHtcbiAgICBjb25zdCBsaXRlcmFsID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkVuY2Fwc2VkfSAqLyAobm9kZSlcbiAgICBjb25zdCBkZXRhaWwgPSBsaXRlcmFsLnR5cGUgPT0gXCJzdHJpbmdcIiA/IFwiaW50ZXJwb2xhdGVkIHN0cmluZ1wiIDogYCR7bGl0ZXJhbC50eXBlfSBzdHJpbmdgXG5cbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgZGV0YWlsLCBsb2NhdGlvbilcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJub3dkb2NcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm93ZG9jIHN0cmluZ1wiLCBsb2NhdGlvbilcblxuICBpZiAobm9kZS5raW5kID09IFwidW5hcnlcIikge1xuICAgIGNvbnN0IHVuYXJ5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlVuYXJ5fSAqLyAobm9kZSlcblxuICAgIGlmICghW1wiIVwiLCBcIi1cIl0uaW5jbHVkZXModW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgdW5hcnkgJHt1bmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG9wZXJhbmQ6IGNvbnZlcnRFeHByZXNzaW9uKHVuYXJ5LndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24odW5hcnkudHlwZSwgdW5hcnkubG9jPy5zdGFydC5vZmZzZXQgPz8gMCwgdW5hcnkud2hhdC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyB1bmFyeS5sb2M/LmVuZC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KSwgdW5hcnkudHlwZSA9PSBcIiFcIiA/IFwiTm90XCIgOiBcIk5lZ2F0ZVwiKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHNlbWFudGljKSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJiaW5cIikge1xuICAgIGNvbnN0IGJpbmFyeSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CaW59ICovIChub2RlKVxuICAgIGlmIChbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKGJpbmFyeS50eXBlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBjb2VyY2l2ZSBlcXVhbGl0eSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmIChbXCJhbmRcIiwgXCJvclwiXS5pbmNsdWRlcyhiaW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgcHJlY2VkZW5jZS1zZW5zaXRpdmUgYm9vbGVhbiAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmICghcGhwQmluYXJ5T3BlcmF0aW9ucy5oYXMoYmluYXJ5LnR5cGUpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYGJpbmFyeSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCaW5hcnlFeHByZXNzaW9uXCIpLFxuICAgICAgbGVmdDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByaWdodDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0sIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChwaHBCaW5hcnlPcGVyYXRpb25zLmdldChiaW5hcnkudHlwZSkpKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHdpdGhQYXJzZXJSYW5nZXMoc2VtYW50aWMsIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKGJpbmFyeS50eXBlLCBiaW5hcnkubGVmdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgYmluYXJ5LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSkpKVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImNhbGxcIikge1xuICAgIGNvbnN0IGNhbGwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2FsbH0gKi8gKG5vZGUpXG5cbiAgICBpZiAoY2FsbC53aGF0LmtpbmQgIT0gXCJuYW1lXCIgJiYgY2FsbC53aGF0LmtpbmQgIT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImR5bmFtaWMgY2FsbFwiLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICBjb25zdCBjYWxsZWUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTmFtZSB8IGltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGNhbGwud2hhdCkubmFtZVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgYXJndW1lbnRzOiBjYWxsLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50KSA9PiBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpLFxuICAgICAgY2FsbGVlLFxuICAgICAga2luZDogXCJDYWxsRXhwcmVzc2lvblwiLFxuICAgICAgbG9jYXRpb25cbiAgICB9LCB7Y2FsbGVlOiBub2RlTG9jYXRpb24oY2FsbC53aGF0LCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH1cblxuICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgbm9kZS5raW5kLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhwbGljaXQgUEhQIHJldHVybi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJldHVyblN0YXRlbWVudH0gU2VtYW50aWMgcmV0dXJuLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UmV0dXJuKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5raW5kICE9IFwicmV0dXJuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBub2RlLmtpbmQsIGxvY2F0aW9uKVxuXG4gIGNvbnN0IHJldHVybk5vZGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUmV0dXJufSAqLyAobm9kZSlcblxuICBpZiAoIXJldHVybk5vZGUuZXhwcikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZW1wdHkgcmV0dXJuXCIsIGxvY2F0aW9uKVxuXG4gIHJldHVybiB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24ocmV0dXJuTm9kZS5leHByLCBmaWxlbmFtZSwgc291cmNlKSwga2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIiwgbG9jYXRpb259XG59XG5cbi8qKlxuICogUmVhZHMgb25lIGV4YWN0IFBIUCBsb2NhbCBgQHZhcmAgY2FycmllciBhbmQgaW1tdXRhYmlsaXR5IG1hcmtlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gQXNzaWdubWVudC1vd25pbmcgc3RhdGVtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NhbCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt7aW1tdXRhYmxlOiBib29sZWFuLCB0eXBlOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSB8IHVuZGVmaW5lZH0gTWV0YWRhdGEgd2hlbiBwcmVzZW50LlxuICovXG5mdW5jdGlvbiBsb2NhbE1ldGFkYXRhKG5vZGUsIG5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgY29tbWVudHMgPSBub2RlLmxlYWRpbmdDb21tZW50cyA/PyBbXVxuICBjb25zdCBjb21tZW50ID0gY29tbWVudHMuYXQoLTEpXG5cbiAgaWYgKCFjb21tZW50IHx8IGNvbW1lbnQua2luZCAhPSBcImNvbW1lbnRibG9ja1wiIHx8ICFjb21tZW50LmxvYyB8fCAhbm9kZS5sb2MpIHJldHVybiB1bmRlZmluZWRcblxuICBjb25zdCBnYXAgPSBzb3VyY2Uuc2xpY2UoY29tbWVudC5sb2MuZW5kLm9mZnNldCwgbm9kZS5sb2Muc3RhcnQub2Zmc2V0KVxuXG4gIGlmICghL15cXHMqJC91LnRlc3QoZ2FwKSB8fCAoZ2FwLm1hdGNoKC9cXG4vZ3UpPy5sZW5ndGggPz8gMCkgPiAxKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgYmxvY2sgPSBwYXJzZUNvbW1lbnQoY29tbWVudC52YWx1ZSlbMF1cbiAgY29uc3QgdGFncyA9IGJsb2NrPy50YWdzID8/IFtdXG4gIGNvbnN0IHZhcmlhYmxlcyA9IHRhZ3MuZmlsdGVyKCh0YWcpID0+IHRhZy50YWcgPT0gXCJ2YXJcIilcbiAgY29uc3QgaW1tdXRhYmxlID0gdGFncy5maWx0ZXIoKHRhZykgPT4gdGFnLnRhZyA9PSBcInNlbWFudGlmb2xkLWltbXV0YWJsZVwiKVxuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmICh2YXJpYWJsZXMubGVuZ3RoID09IDAgJiYgaW1tdXRhYmxlLmxlbmd0aCA9PSAwKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgZXhhY3RWYXJpYWJsZSA9IHZhcmlhYmxlcy5sZW5ndGggPT0gMSAmJiB2YXJpYWJsZXNbMF0udHlwZSA9PSBcIlwiICYmIHZhcmlhYmxlc1swXS5kZXNjcmlwdGlvbiA9PSBgJCR7bmFtZX1gXG4gIGNvbnN0IGV4YWN0SW1tdXRhYmxlID0gaW1tdXRhYmxlLmxlbmd0aCA8PSAxICYmIGltbXV0YWJsZS5ldmVyeSgodGFnKSA9PiB0YWcubmFtZSA9PSBcIlwiICYmIHRhZy50eXBlID09IFwiXCIgJiYgdGFnLmRlc2NyaXB0aW9uID09IFwiXCIpXG4gIGNvbnN0IGtub3duVGFncyA9IHRhZ3MuZXZlcnkoKHRhZykgPT4gdGFnLnRhZyA9PSBcInZhclwiIHx8IHRhZy50YWcgPT0gXCJzZW1hbnRpZm9sZC1pbW11dGFibGVcIilcblxuICBpZiAoIWV4YWN0VmFyaWFibGUgfHwgIWV4YWN0SW1tdXRhYmxlIHx8ICFrbm93blRhZ3MpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJtYWxmb3JtZWQgbG9jYWwgdHlwZSBtZXRhZGF0YVwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgaW1tdXRhYmxlOiBpbW11dGFibGUubGVuZ3RoID09IDEsXG4gICAgdHlwZTogcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUoXG4gICAgICBcInBocFwiLFxuICAgICAgdmFyaWFibGVzWzBdLm5hbWUsXG4gICAgICBgTG9jYWwgJyR7bmFtZX0nYCxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHZhcmlhYmxlc1swXSwgXCJuYW1lXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgKVxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIFBIUCBsb2NhbCBkZWNsYXJhdGlvbiBvciBhc3NpZ25tZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgc3RhdGVtZW50LlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdmlzaWJsZSAtIE5hbWVzIHZpc2libGUgZHVyaW5nIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkxvY2FsU3RhdGVtZW50fSBTZW1hbnRpYyBsb2NhbCBzdGF0ZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRMb2NhbFN0YXRlbWVudChub2RlLCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUua2luZCAhPSBcImV4cHJlc3Npb25zdGF0ZW1lbnRcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIG5vZGUua2luZCwgbG9jYXRpb24pXG5cbiAgY29uc3QgZXhwcmVzc2lvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FeHByZXNzaW9uU3RhdGVtZW50fSAqLyAobm9kZSkuZXhwcmVzc2lvblxuXG4gIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJhc3NpZ25cIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGV4cHJlc3Npb24ua2luZCwgbm9kZUxvY2F0aW9uKGV4cHJlc3Npb24sIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gIGNvbnN0IGFzc2lnbm1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQXNzaWdufSAqLyAoZXhwcmVzc2lvbilcblxuICBpZiAoYXNzaWdubWVudC5vcGVyYXRvciAhPSBcIj1cIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBhc3NpZ25tZW50ICR7YXNzaWdubWVudC5vcGVyYXRvcn1gLCBsb2NhdGlvbilcbiAgaWYgKGFzc2lnbm1lbnQubGVmdC5raW5kICE9IFwidmFyaWFibGVcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGFzc2lnbm1lbnQubGVmdC5raW5kLCBub2RlTG9jYXRpb24oYXNzaWdubWVudC5sZWZ0LCBmaWxlbmFtZSwgc291cmNlKSlcblxuICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKGFzc2lnbm1lbnQubGVmdClcbiAgY29uc3QgdGFyZ2V0TG9jYXRpb24gPSBub2RlTG9jYXRpb24odmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKHR5cGVvZiB2YXJpYWJsZS5uYW1lICE9IFwic3RyaW5nXCIgfHwgdmFyaWFibGUuY3VybHkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImR5bmFtaWMgdmFyaWFibGVcIiwgdGFyZ2V0TG9jYXRpb24pXG5cbiAgY29uc3QgbWV0YWRhdGEgPSBsb2NhbE1ldGFkYXRhKG5vZGUsIHZhcmlhYmxlLm5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG1ldGFkYXRhKSB7XG4gICAgdmlzaWJsZS5hZGQodmFyaWFibGUubmFtZSlcbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBpbml0aWFsaXplcjogY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBraW5kOiBcIkxvY2FsRGVjbGFyYXRpb25cIixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgbXV0YWJsZTogIW1ldGFkYXRhLmltbXV0YWJsZSxcbiAgICAgIG5hbWU6IHZhcmlhYmxlLm5hbWUsXG4gICAgICB0eXBlOiBtZXRhZGF0YS50eXBlXG4gICAgfSwge1xuICAgICAgbmFtZTogdGFyZ2V0TG9jYXRpb24sXG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIGlmICghdmlzaWJsZS5oYXModmFyaWFibGUubmFtZSkpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgTG9jYWwgJyR7dmFyaWFibGUubmFtZX0nYCwgbG9jYXRpb24pXG5cbiAgY29uc3QgdGFyZ2V0ID0gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiksIGxvY2F0aW9uOiB0YXJnZXRMb2NhdGlvbiwgbmFtZTogdmFyaWFibGUubmFtZX0sIHtcbiAgICBuYW1lOiB0YXJnZXRMb2NhdGlvblxuICB9KVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBleHByZXNzaW9uOiBjb252ZXJ0RXhwcmVzc2lvbihhc3NpZ25tZW50LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBraW5kOiBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvbixcbiAgICB0YXJnZXRcbiAgfSwge1xuICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiPVwiLCBhc3NpZ25tZW50LmxlZnQubG9jPy5lbmQub2Zmc2V0ID8/IDAsIGFzc2lnbm1lbnQucmlnaHQubG9jPy5zdGFydC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhoYXVzdGl2ZSBQSFAgc3RhdGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgc3RhdGVtZW50LlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdmlzaWJsZSAtIE5hbWVzIHZpc2libGUgZHVyaW5nIGFkYXB0YXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU2VtYW50aWMgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0U3RhdGVtZW50KG5vZGUsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKG5vZGUua2luZCA9PSBcInJldHVyblwiKSByZXR1cm4gY29udmVydFJldHVybihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICBpZiAobm9kZS5raW5kID09IFwiaWZcIikgcmV0dXJuIGNvbnZlcnRJZigvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWZ9ICovIChub2RlKSwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgaWYgKG5vZGUua2luZCA9PSBcImVjaG9cIikgcmV0dXJuIGNvbnZlcnRQcmludCgvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRWNob30gKi8gKG5vZGUpLCBmaWxlbmFtZSwgc291cmNlKVxuICBpZiAobm9kZS5raW5kID09IFwiZXhwcmVzc2lvbnN0YXRlbWVudFwiKSByZXR1cm4gY29udmVydExvY2FsU3RhdGVtZW50KG5vZGUsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIG5vZGUua2luZCwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGFuIG9yZGVyZWQgUEhQIGJsb2NrIHdpdGggaXRzIG93biBhZGFwdGF0aW9uIHNjb3BlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSBub2RlIC0gUEhQIHBhcnNlciBibG9jay5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHZpc2libGUgLSBOYW1lcyB2aXNpYmxlIG9uIGJsb2NrIGVudHJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gU2VtYW50aWMgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhub2RlLCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIHJldHVybiB7XG4gICAga2luZDogXCJCbG9ja1wiLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgc3RhdGVtZW50czogbm9kZS5jaGlsZHJlbi5tYXAoKHN0YXRlbWVudCkgPT4gY29udmVydFN0YXRlbWVudChzdGF0ZW1lbnQsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG59XG5cbi8qKlxuICogUmVxdWlyZXMgYW4gZXhhY3QgUEhQIHNjYWxhciBkZWNsYXJhdGlvbiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGUgfCBudWxsfSBzb3VyY2VUeXBlIC0gUEhQIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gU291cmNlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUmVmZXJlbmNlfSBTZW1hbnRpYyB0eXBlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0VHlwZShzb3VyY2VUeXBlLCBzdWJqZWN0LCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIXNvdXJjZVR5cGUpIHJldHVybiByZXF1aXJlU291cmNlU2NhbGFyVHlwZShcInBocFwiLCB1bmRlZmluZWQsIHN1YmplY3QsIGxvY2F0aW9uKVxuICBpZiAoc291cmNlVHlwZS5raW5kICE9IFwidHlwZXJlZmVyZW5jZVwiICYmIHNvdXJjZVR5cGUua2luZCAhPSBcIm5hbWVcIiAmJiBzb3VyY2VUeXBlLmtpbmQgIT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJ1bnN1cHBvcnRlZCBzY2FsYXIgdHlwZVwiLCBub2RlTG9jYXRpb24oc291cmNlVHlwZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICBjb25zdCB0eXBlTmFtZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5UeXBlUmVmZXJlbmNlIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAoc291cmNlVHlwZSkubmFtZVxuXG4gIHJldHVybiByZXF1aXJlU291cmNlU2NhbGFyVHlwZShcInBocFwiLCB0eXBlTmFtZSwgc3ViamVjdCwgbG9jYXRpb24sIG5vZGVMb2NhdGlvbihzb3VyY2VUeXBlLCBmaWxlbmFtZSwgc291cmNlKSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIFBIUCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIFBIUCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG5cbiAgaWYgKCFub2RlLmJvZHkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiBib2R5XCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgcGFyYW1ldGVycyA9IG5vZGUuYXJndW1lbnRzLm1hcCgocGFyYW1ldGVyKSA9PiB7XG4gICAgY29uc3QgcGFyYW1ldGVyTG9jYXRpb24gPSBub2RlTG9jYXRpb24ocGFyYW1ldGVyLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IHBhcmFtZXRlck5hbWUgPSB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZVxuXG4gICAgaWYgKHBhcmFtZXRlci5udWxsYWJsZSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwidW5zdXBwb3J0ZWQgc2NhbGFyIHR5cGVcIiwgcGFyYW1ldGVyTG9jYXRpb24pXG5cbiAgICBjb25zdCBwYXJhbWV0ZXJOb2RlID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIgOiBwYXJhbWV0ZXIubmFtZVxuICAgIGNvbnN0IHNlbWFudGljUGFyYW1ldGVyID0ge1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUGFyYW1ldGVyXCIpLFxuICAgICAgbG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgbmFtZTogcGFyYW1ldGVyTmFtZSxcbiAgICAgIHR5cGU6IGNvbnZlcnRUeXBlKHBhcmFtZXRlci50eXBlLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHNlbWFudGljUGFyYW1ldGVyLCB7bmFtZTogbm9kZUxvY2F0aW9uKHBhcmFtZXRlck5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfSlcbiAgaWYgKG5vZGUubnVsbGFibGUpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIsIGxvY2F0aW9uKVxuICBjb25zdCB2aXNpYmxlID0gbmV3IFNldChwYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIubmFtZSkpXG4gIGNvbnN0IGJvZHkgPSBjb252ZXJ0QmxvY2sobm9kZS5ib2R5LCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGNvbnN0IG5hbWVOb2RlID0gdHlwZW9mIG5vZGUubmFtZSA9PSBcInN0cmluZ1wiID8gbm9kZSA6IG5vZGUubmFtZVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBib2R5LFxuICAgIGtpbmQ6IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiLFxuICAgIGxvY2F0aW9uLFxuICAgIG5hbWUsXG4gICAgcGFyYW1ldGVycyxcbiAgICByZXR1cm5UeXBlOiBjb252ZXJ0VHlwZShub2RlLnR5cGUsIGBGdW5jdGlvbiAnJHtuYW1lfScgcmV0dXJuYCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0sIHtuYW1lOiBub2RlTG9jYXRpb24obmFtZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZXhpc3RpbmcgUEhQIGlmL2Vsc2UgdGVybWluYWwgd2l0aCByZXN0cmljdGVkIGJyYW5jaCBwcmVmaXhlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gbm9kZSAtIFBIUCBpZiBub2RlLlxuICogQHBhcmFtIHtTZXQ8c3RyaW5nPn0gdmlzaWJsZSAtIEVuY2xvc2luZyB2aXNpYmxlIG5hbWVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gU2VtYW50aWMgYnJhbmNoLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0SWYobm9kZSwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnNob3J0Rm9ybSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiYWx0ZXJuYXRpdmUgaWYgc3ludGF4XCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5ib2R5LmtpbmQgIT0gXCJibG9ja1wiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJpZiB3aXRob3V0IGJsb2NrIGNvbnNlcXVlbnRcIiwgbG9jYXRpb24pXG5cbiAgY29uc3QgY29uc2VxdWVudFZpc2libGUgPSBuZXcgU2V0KHZpc2libGUpXG4gIGxldCBhbHRlcm5hdGVcblxuICBpZiAobm9kZS5hbHRlcm5hdGUpIHtcbiAgICBjb25zdCBhbHRlcm5hdGVWaXNpYmxlID0gbmV3IFNldCh2aXNpYmxlKVxuXG4gICAgaWYgKG5vZGUuYWx0ZXJuYXRlLmtpbmQgPT0gXCJibG9ja1wiKSB7XG4gICAgICBhbHRlcm5hdGUgPSBjb252ZXJ0QmxvY2soLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5hbHRlcm5hdGUpLCBhbHRlcm5hdGVWaXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0gZWxzZSBpZiAobm9kZS5hbHRlcm5hdGUua2luZCA9PSBcImlmXCIpIHtcbiAgICAgIGNvbnN0IG5lc3RlZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gKi8gKG5vZGUuYWx0ZXJuYXRlKVxuXG4gICAgICBhbHRlcm5hdGUgPSB7XG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5lc3RlZCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIHN0YXRlbWVudHM6IFtjb252ZXJ0SWYobmVzdGVkLCBhbHRlcm5hdGVWaXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKV1cbiAgICAgIH1cbiAgICB9IGVsc2UgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBpZiBhbHRlcm5hdGUgJHtub2RlLmFsdGVybmF0ZS5raW5kfWAsIG5vZGVMb2NhdGlvbihub2RlLmFsdGVybmF0ZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLihhbHRlcm5hdGUgPyB7YWx0ZXJuYXRlfSA6IHt9KSxcbiAgICBjb25kaXRpb246IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUudGVzdCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgY29uc2VxdWVudDogY29udmVydEJsb2NrKG5vZGUuYm9keSwgY29uc2VxdWVudFZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIGtpbmQ6IFwiSWZTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBQSFAgZWNobyBlbnRyeSBwb2ludC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FY2hvfSBub2RlIC0gUEhQIGVjaG8gbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUHJpbnRTdGF0ZW1lbnR9IFByaW50IHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydFByaW50KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5leHByZXNzaW9ucy5sZW5ndGggIT0gMiB8fCBub2RlLmV4cHJlc3Npb25zWzFdLmtpbmQgIT0gXCJuYW1lXCIgfHxcbiAgICAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTmFtZX0gKi8gKG5vZGUuZXhwcmVzc2lvbnNbMV0pLm5hbWUgIT0gXCJQSFBfRU9MXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJlY2hvIHdpdGhvdXQgb25lIGV4cHJlc3Npb24gYW5kIFBIUF9FT0xcIiwgbG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4ge2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUuZXhwcmVzc2lvbnNbMF0sIGZpbGVuYW1lLCBzb3VyY2UpLCBraW5kOiBcIlByaW50U3RhdGVtZW50XCIsIGxvY2F0aW9ufVxufVxuXG4vKipcbiAqIFBhcnNlcyBQSFAgaW50byB0aGUgc2hhcmVkIHNlbWFudGljIG1vZHVsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBpbnB1dCAtIFBhcnNlciBpbnB1dC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5maWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5zb3VyY2UgLSBTb3VyY2UgdGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VQaHAoe2ZpbGVuYW1lLCBzb3VyY2V9KSB7XG4gIGNvbnN0IHByb2dyYW0gPSBwYXJzZVBocFByb2dyYW0oZmlsZW5hbWUsIHNvdXJjZSlcbiAgdmFsaWRhdGVEZWNsYXJlTm9kZXMocHJvZ3JhbS5jaGlsZHJlbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgZnVuY3Rpb25zID0gcHJvZ3JhbS5jaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCA9PSBcImZ1bmN0aW9uXCIpXG4gICAgLm1hcCgobm9kZSkgPT4gY29udmVydEZ1bmN0aW9uKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gKi8gKG5vZGUpLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgZXhlY3V0YWJsZU5vZGVzID0gcHJvZ3JhbS5jaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCAhPSBcImZ1bmN0aW9uXCIgJiYgbm9kZS5raW5kICE9IFwiZGVjbGFyZVwiICYmIG5vZGUua2luZCAhPSBcIm5vb3BcIilcbiAgY29uc3QgbG9jYXRpb24gPSBtb2R1bGVMb2NhdGlvbihmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChmdW5jdGlvbnMubGVuZ3RoID09IDApIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1vZHVsZSB3aXRob3V0IGEgZnVuY3Rpb25cIiwgbG9jYXRpb24pXG4gIGNvbnN0IGZpcnN0ID0gZXhlY3V0YWJsZU5vZGVzWzBdXG4gIGNvbnN0IGxhc3QgPSBleGVjdXRhYmxlTm9kZXMuYXQoLTEpID8/IGZpcnN0XG4gIGNvbnN0IGVudHJ5TG9jYXRpb24gPSBmaXJzdFxuICAgID8gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBmaXJzdC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBsYXN0Py5sb2M/LmVuZC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aClcbiAgICA6IGxvY2F0aW9uXG4gIGNvbnN0IGVudHJ5VmlzaWJsZSA9IG5ldyBTZXQoKVxuICBjb25zdCBlbnRyeUJsb2NrID0ge1xuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLFxuICAgIGxvY2F0aW9uOiBlbnRyeUxvY2F0aW9uLFxuICAgIHN0YXRlbWVudHM6IGV4ZWN1dGFibGVOb2Rlcy5tYXAoKG5vZGUpID0+IGNvbnZlcnRTdGF0ZW1lbnQobm9kZSwgZW50cnlWaXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZW50cnlQb2ludDoge1xuICAgICAgYm9keTogZW50cnlCbG9jayxcbiAgICAgIGtpbmQ6IFwiRW50cnlQb2ludFwiLFxuICAgICAgbG9jYXRpb246IGVudHJ5TG9jYXRpb25cbiAgICB9LFxuICAgIGZ1bmN0aW9ucyxcbiAgICBraW5kOiBcIk1vZHVsZVwiLFxuICAgIGxvY2F0aW9uXG4gIH1cbn1cblxuLyoqXG4gKiBBY2NlcHRzIG9ubHkgYW4gb3B0aW9uYWwgc2luZ2xlIGBkZWNsYXJlKHN0cmljdF90eXBlcz0xKWAgZGlyZWN0aXZlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGVbXX0gbm9kZXMgLSBUb3AtbGV2ZWwgUEhQIG5vZGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZURlY2xhcmVOb2Rlcyhub2RlcywgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBub2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCA9PSBcImRlY2xhcmVcIilcblxuICBpZiAoZGVjbGFyYXRpb25zLmxlbmd0aCA+IDEpIHtcbiAgICB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm11bHRpcGxlIGRlY2xhcmUgZGlyZWN0aXZlc1wiLCBub2RlTG9jYXRpb24oZGVjbGFyYXRpb25zWzFdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb25Ob2RlIG9mIGRlY2xhcmF0aW9ucykge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkRlY2xhcmV9ICovIChkZWNsYXJhdGlvbk5vZGUpXG4gICAgY29uc3QgZGlyZWN0aXZlID0gZGVjbGFyYXRpb24uZGlyZWN0aXZlc1swXVxuICAgIGNvbnN0IGtleSA9IGRpcmVjdGl2ZT8ua2V5XG4gICAgY29uc3QgdmFsdWUgPSBkaXJlY3RpdmU/LnZhbHVlXG4gICAgY29uc3QgbnVtZXJpY1ZhbHVlID0gdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09IFwib2JqZWN0XCIgJiYgdmFsdWUua2luZCA9PSBcIm51bWJlclwiXG4gICAgICA/IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OdW1iZXJ9ICovICh2YWx1ZSlcbiAgICAgIDogdW5kZWZpbmVkXG4gICAgY29uc3QgdmFsdWVJc09uZSA9IG51bWVyaWNWYWx1ZT8ubG9jICYmIHNvdXJjZS5zbGljZShudW1lcmljVmFsdWUubG9jLnN0YXJ0Lm9mZnNldCwgbnVtZXJpY1ZhbHVlLmxvYy5lbmQub2Zmc2V0KSA9PSBcIjFcIlxuICAgIGNvbnN0IHZhbGlkID0gZGVjbGFyYXRpb24ubW9kZSA9PSBcIm5vbmVcIiAmJiBkZWNsYXJhdGlvbi5jaGlsZHJlbi5sZW5ndGggPT0gMCAmJiBkZWNsYXJhdGlvbi5kaXJlY3RpdmVzLmxlbmd0aCA9PSAxICYmXG4gICAgICBrZXkua2luZCA9PSBcImlkZW50aWZpZXJcIiAmJiBrZXkubmFtZSA9PSBcInN0cmljdF90eXBlc1wiICYmIHZhbHVlSXNPbmVcblxuICAgIGlmICghdmFsaWQpIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZGVjbGFyZSBvdGhlciB0aGFuIHN0cmljdF90eXBlcz0xXCIsIG5vZGVMb2NhdGlvbihkZWNsYXJhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbn1cblxuLyoqXG4gKiBJbnZva2VzIHBocC1wYXJzZXIgYW5kIG5vcm1hbGl6ZXMgc3ludGF4IGZhaWx1cmVzLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIFNvdXJjZSB0ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcInBocC1wYXJzZXJcIikuUHJvZ3JhbX0gUEhQIHByb2dyYW0uXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGhwUHJvZ3JhbShmaWxlbmFtZSwgc291cmNlKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIHBhcnNlci5wYXJzZUNvZGUoc291cmNlLCBmaWxlbmFtZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gcGFyc2VGYWlsdXJlKFwicGhwXCIsIGVycm9yKVxuICB9XG59XG4iXX0=
|
|
2030
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGhwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9waHAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sU0FBUyxNQUFNLFlBQVksQ0FBQTtBQUNsQyxPQUFPLEVBQUMsS0FBSyxJQUFJLFlBQVksRUFBQyxNQUFNLGdCQUFnQixDQUFBO0FBQ3BELE9BQU8sRUFBQyxXQUFXLEVBQUUsWUFBWSxFQUFFLGlCQUFpQixFQUFDLE1BQU0sa0JBQWtCLENBQUE7QUFDN0UsT0FBTyxFQUFDLDZCQUE2QixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDcEUsT0FBTyxFQUFDLG1CQUFtQixFQUFFLGNBQWMsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQzNFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLDBCQUEwQixDQUFBO0FBQzdELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJCQUEyQixDQUFBO0FBQzFELE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLDZCQUE2QixDQUFBO0FBQ2xFLE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBQzVELE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxVQUFVLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUN4RSxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUMvRCxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsdUJBQXVCLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDL0YsT0FBTyxFQUFDLDRCQUE0QixFQUFFLG1CQUFtQixFQUFFLDJCQUEyQixFQUFFLG9CQUFvQixFQUFFLG9CQUFvQixFQUFFLHVCQUF1QixFQUFFLG1CQUFtQixFQUFFLFlBQVksRUFBRSxxQkFBcUIsRUFBRSxpQkFBaUIsRUFBRSxnQ0FBZ0MsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBQyxNQUFNLFlB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Q0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUM7UUFBRSxPQUFPLEVBQUMsVUFBVSxFQUFFLElBQUksR0FBRyxFQUFFLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBQyxDQUFBO0lBQ3BJLE1BQU0sS0FBSyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7SUFDNUMsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLElBQUksSUFBSSxFQUFFLENBQUE7SUFDOUIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQTtJQUM5RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLFFBQVEsSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLFNBQVMsQ0FBQyxDQUFBO0lBQ3BGLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksVUFBVSxDQUFDLENBQUE7SUFDaEUsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxJQUFJLFVBQVUsQ0FBQyxDQUFBO0lBQ3JHLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxVQUFVLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksVUFBVSxDQUFDLE1BQU0sR0FBRyxDQUFDO1FBQzFILGFBQWEs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R0FBRyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUE7SUFFdkQsT0FBTyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7QUFDM0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgUGhwUGFyc2VyIGZyb20gXCJwaHAtcGFyc2VyXCJcbmltcG9ydCB7cGFyc2UgYXMgcGFyc2VDb21tZW50fSBmcm9tIFwiY29tbWVudC1wYXJzZXJcIlxuaW1wb3J0IHttaXNzaW5nVHlwZSwgcGFyc2VGYWlsdXJlLCB1bnN1cHBvcnRlZFN5bnRheH0gZnJvbSBcIi4uL2RpYWdub3N0aWMuanNcIlxuaW1wb3J0IHtibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeX0gZnJvbSBcIi4uL3NlbWFudGljL2VmZmVjdHMuanNcIlxuaW1wb3J0IHtsb2NhdGlvbkZyb21PZmZzZXRzLCBtb2R1bGVMb2NhdGlvbn0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7d2l0aEFkYXB0ZWRPcGVyYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIlxuaW1wb3J0IHt3aXRoUGFyc2VyUmFuZ2VzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge2lzVGFzazAzNFJlc291cmNlUHJvYmV9IGZyb20gXCIuLi9zZW1hbnRpYy9jYXBhYmlsaXRpZXMuanNcIlxuaW1wb3J0IHtoYXNFeGFjdEVmZmVjdFN1cHBvcnR9IGZyb20gXCIuLi9iYWNrZW5kcy9lZmZlY3RzLmpzXCJcbmltcG9ydCB7aGFzT25seVVuaWNvZGVTY2FsYXJzLCBzY2FsYXJUeXBlfSBmcm9tIFwiLi4vc2VtYW50aWMvc2NhbGFycy5qc1wiXG5pbXBvcnQge3R5cGVDb250YWluc0FueVZhcmlhYmxlfSBmcm9tIFwiLi4vc2VtYW50aWMvZ2VuZXJpY3MuanNcIlxuaW1wb3J0IHtyZXF1aXJlU291cmNlUmV0dXJuVHlwZSwgcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUsIHNvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuaW1wb3J0IHtjYXBhYmlsaXR5RnVuY3Rpb25TaWduYXR1cmVzLCBkb2N1bWVudGVkVmFsdWVUeXBlLCBpbnN0YW50aWF0ZWRSZWNvcmRGaWVsZFR5cGUsIGl0ZXJhdGlvbkJpbmRpbmdUeXBlLCBpdGVyYXRpb25PcGVyYW5kVHlwZSwga25vd25DYWxsUGFyYW1ldGVyVHlwZXMsIGtub3duQ2FsbFJldHVyblR5cGUsIG9wdGlvbmFsVHlwZSwgb3JkZXJlZE1hcFR5cGVGcm9tTWFwLCBvd25lZFJlc291cmNlVHlwZSwgcHJlc2VydmVzR2VuZXJpY09wdGlvbmFsRXZpZGVuY2UsIHJlY29yZFR5cGUsIHJlZmVyZW5jZVR5cGUsIHNhbWVWYWx1ZVR5cGV9IGZyb20gXCIuL3R5cGVzLmpzXCJcbmNvbnN0IHBhcnNlciA9IG5ldyBQaHBQYXJzZXIuRW5naW5lKHtcbiAgYXN0OiB7d2l0aFBvc2l0aW9uczogdHJ1ZX0sXG4gIHBhcnNlcjoge2V4dHJhY3REb2M6IHRydWUsIHN1cHByZXNzRXJyb3JzOiBmYWxzZX1cbn0pXG4vKiogQHR5cGUge3N0cmluZyB8IHVuZGVmaW5lZH0gKi9cbmxldCBjYWNoZWRUb2tlblNvdXJjZVxuLyoqIEB0eXBlIHt7ZW5kOiBudW1iZXIsIHN0YXJ0OiBudW1iZXIsIHRleHQ6IHN0cmluZ31bXX0gKi9cbmxldCBjYWNoZWRUb2tlblJhbmdlcyA9IFtdXG5jb25zdCBwaHBCaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJQaHBBZGRcIl0sXG4gIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wiKlwiLCBcIk11bHRpcGx5XCJdLFxuICBbXCImJlwiLCBcIkFuZFwiXSxcbiAgW1wifHxcIiwgXCJPclwiXSxcbiAgW1wiPT09XCIsIFwiRXF1YWxcIl0sXG4gIFtcIiE9PVwiLCBcIk5vdEVxdWFsXCJdLFxuICBbXCI8XCIsIFwiTGVzc1RoYW5cIl0sXG4gIFtcIjw9XCIsIFwiTGVzc1RoYW5PckVxdWFsXCJdLFxuICBbXCI+XCIsIFwiR3JlYXRlclRoYW5cIl0sXG4gIFtcIj49XCIsIFwiR3JlYXRlclRoYW5PckVxdWFsXCJdLFxuICBbXCIuXCIsIFwiU3RyaW5nQ29uY2F0XCJdXG5dKVxuXG4vKipcbiAqIEB0eXBlZGVmIFBocENvbnZlcnNpb25Db250ZXh0XG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljQmluZGluZ1R5cGU+fSBiaW5kaW5ncyAtIEV4cGxpY2l0bHkgdHlwZWQgdmlzaWJsZSBiaW5kaW5ncy5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbj59IGNsYXNzZXMgLSBSZWZlcmVuY2UgY2xhc3NlcyBieSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gW2N1cnJlbnRDbGFzc10gLSBFbmNsb3NpbmcgcmVmZXJlbmNlIGNsYXNzLlxuICogQHByb3BlcnR5IHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gZXJyb3JOYW1lcyAtIEVycm9yIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbj59IGVycm9ycyAtIEVycm9yIGRlY2xhcmF0aW9ucyBieSBpZGVudGl0eS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgUGhwRnVuY3Rpb25TaWduYXR1cmU+fSBmdW5jdGlvbnMgLSBFeHBsaWNpdCBtb2R1bGUgZnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwcm9wZXJ0eSB7U2V0PG9iamVjdD59IFtvcmRlcmVkTWFwRGVjbGFyYXRpb25zXSAtIEV4YWN0IGxvY2FsIGRlY2xhcmF0aW9ucyBzZWxlY3RlZCBieSBwYXJzZXItb3duZWQgcGFpciBpdGVyYXRpb24uXG4gKiBAcHJvcGVydHkge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSByZWNvcmROYW1lcyAtIE5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHByb3BlcnR5IHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IHJlY29yZHMgLSBSZWNvcmQgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IHVuZGVmaW5lZH0gcmV0dXJuVHlwZSAtIEVuY2xvc2luZyByZXR1cm4gdHlwZS5cbiAqIEBwcm9wZXJ0eSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcj59IFt0eXBlUGFyYW1ldGVyc10gLSBEZWNsYXJhdGlvbi1zY29wZWQgcGFyYW1ldGVycy5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIFBocEZ1bmN0aW9uU2lnbmF0dXJlXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIENvbXBsZXRlIGRlY2xhcmF0aW9uIGxvY2F0aW9uLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gbmFtZUxvY2F0aW9uIC0gUGFyc2VyLW93bmVkIG5hbWUgbG9jYXRpb24uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gbmFtZSAtIEZ1bmN0aW9uIG5hbWUuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gU2VtYW50aWMgcGFyYW1ldGVycy5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9IHJldHVyblR5cGUgLSBTZW1hbnRpYyByZXR1cm4gdHlwZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcltdfSBbdHlwZVBhcmFtZXRlcnNdIC0gRGVjbGFyYXRpb24tc2NvcGVkIHBhcmFtZXRlcnMuXG4gKi9cblxuLyoqXG4gKiBSZXR1cm5zIGEgbm9ybWFsaXplZCBQSFAgbm9kZSBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIHBhcnNlciBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gU291cmNlIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIW5vZGUubG9jKSB0aHJvdyBuZXcgRXJyb3IoYFBIUCBwYXJzZXIgb21pdHRlZCBzb3VyY2UgbG9jYXRpb24gZm9yICR7bm9kZS5raW5kfS5gKVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIG5vZGUubG9jLnN0YXJ0Lm9mZnNldCwgbm9kZS5sb2MuZW5kLm9mZnNldClcbn1cblxuLyoqXG4gKiBMb2NhdGVzIGEgY29tbWVudC1wYXJzZXIgdG9rZW4gaW5zaWRlIGEgUEhQIHBhcnNlci1vd25lZCBkb2MgY29tbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Db21tZW50QmxvY2t9IGNvbW1lbnQgLSBQSFAgZG9jIGNvbW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcImNvbW1lbnQtcGFyc2VyXCIpLlNwZWN9IHRhZyAtIFBhcnNlZCBkb2MgdGFnLlxuICogQHBhcmFtIHtcIm5hbWVcIiB8IFwidHlwZVwifSBmaWVsZCAtIFRva2VuIGZpZWxkLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgdG9rZW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGNvbW1lbnRUYWdMb2NhdGlvbihjb21tZW50LCB0YWcsIGZpZWxkLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxpbmUgPSB0YWcuc291cmNlWzBdXG5cbiAgaWYgKCFjb21tZW50LmxvYyB8fCAhbGluZSkgdGhyb3cgbmV3IEVycm9yKGBDb21tZW50IHBhcnNlciBvbWl0dGVkIHRoZSBAJHt0YWcudGFnfSBzb3VyY2UgdG9rZW4uYClcblxuICBsZXQgbGluZVN0YXJ0ID0gY29tbWVudC5sb2Muc3RhcnQub2Zmc2V0XG5cbiAgZm9yIChsZXQgbGluZU51bWJlciA9IDA7IGxpbmVOdW1iZXIgPCBsaW5lLm51bWJlcjsgbGluZU51bWJlcisrKSB7XG4gICAgd2hpbGUgKGxpbmVTdGFydCA8IHNvdXJjZS5sZW5ndGggJiYgc291cmNlW2xpbmVTdGFydF0gIT0gXCJcXHJcIiAmJiBzb3VyY2VbbGluZVN0YXJ0XSAhPSBcIlxcblwiKSBsaW5lU3RhcnQrK1xuICAgIGlmIChzb3VyY2VbbGluZVN0YXJ0XSA9PSBcIlxcclwiICYmIHNvdXJjZVtsaW5lU3RhcnQgKyAxXSA9PSBcIlxcblwiKSBsaW5lU3RhcnQgKz0gMlxuICAgIGVsc2UgbGluZVN0YXJ0KytcbiAgfVxuXG4gIGNvbnN0IG9yZGVyZWRGaWVsZHMgPSBbXCJzdGFydFwiLCBcImRlbGltaXRlclwiLCBcInBvc3REZWxpbWl0ZXJcIiwgXCJ0YWdcIiwgXCJwb3N0VGFnXCIsIFwibmFtZVwiLCBcInBvc3ROYW1lXCIsIFwidHlwZVwiXVxuICBjb25zdCBmaWVsZEluZGV4ID0gb3JkZXJlZEZpZWxkcy5pbmRleE9mKGZpZWxkKVxuICBjb25zdCBzdGFydCA9IGxpbmVTdGFydCArIG9yZGVyZWRGaWVsZHMuc2xpY2UoMCwgZmllbGRJbmRleCkucmVkdWNlKChsZW5ndGgsIGtleSkgPT5cbiAgICBsZW5ndGggKyBsaW5lLnRva2Vuc1svKiogQHR5cGUge2tleW9mIHR5cGVvZiBsaW5lLnRva2Vuc30gKi8gKGtleSldLmxlbmd0aCwgMClcbiAgY29uc3QgdmFsdWUgPSBsaW5lLnRva2Vuc1tmaWVsZF1cblxuICByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBzdGFydCwgc3RhcnQgKyB2YWx1ZS5sZW5ndGgpXG59XG5cbi8qKlxuICogRmluZHMgb25lIHBhcnNlciB0b2tlbiBiZXR3ZWVuIHBhcnNlci1vd25lZCBub2RlIGJvdW5kYXJpZXMuXG4gKiBAcGFyYW0ge3N0cmluZ30gdG9rZW5UZXh0IC0gRXhhY3QgdG9rZW4gdGV4dC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydE9mZnNldCAtIEluY2x1c2l2ZSBzZWFyY2ggYm91bmRhcnkuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kT2Zmc2V0IC0gRXhjbHVzaXZlIHNlYXJjaCBib3VuZGFyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFRva2VuIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiB0b2tlbkxvY2F0aW9uKHRva2VuVGV4dCwgc3RhcnRPZmZzZXQsIGVuZE9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoY2FjaGVkVG9rZW5Tb3VyY2UgIT0gc291cmNlKSB7XG4gICAgbGV0IG9mZnNldCA9IDBcblxuICAgIGNhY2hlZFRva2VuUmFuZ2VzID0gcGFyc2VyLnRva2VuR2V0QWxsKHNvdXJjZSkubWFwKCh0b2tlbikgPT4ge1xuICAgICAgY29uc3QgdGV4dCA9IHR5cGVvZiB0b2tlbiA9PSBcInN0cmluZ1wiID8gdG9rZW4gOiB0b2tlblsxXVxuICAgICAgY29uc3QgcmFuZ2UgPSB7ZW5kOiBvZmZzZXQgKyB0ZXh0Lmxlbmd0aCwgc3RhcnQ6IG9mZnNldCwgdGV4dH1cblxuICAgICAgb2Zmc2V0ID0gcmFuZ2UuZW5kXG5cbiAgICAgIHJldHVybiByYW5nZVxuICAgIH0pXG4gICAgY2FjaGVkVG9rZW5Tb3VyY2UgPSBzb3VyY2VcbiAgfVxuXG4gIGNvbnN0IHRva2VuID0gY2FjaGVkVG9rZW5SYW5nZXMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUudGV4dCA9PSB0b2tlblRleHQgJiYgY2FuZGlkYXRlLnN0YXJ0ID49IHN0YXJ0T2Zmc2V0ICYmXG4gICAgY2FuZGlkYXRlLmVuZCA8PSBlbmRPZmZzZXQpXG5cbiAgaWYgKHRva2VuKSByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCB0b2tlbi5zdGFydCwgdG9rZW4uZW5kKVxuXG4gIHRocm93IG5ldyBFcnJvcihgUEhQIHBhcnNlciBvbWl0dGVkIHRva2VuICcke3Rva2VuVGV4dH0nIGJldHdlZW4gJHtzdGFydE9mZnNldH0gYW5kICR7ZW5kT2Zmc2V0fS5gKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgc3VwcG9ydGVkIFBIUCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkV4cHJlc3Npb259IG5vZGUgLSBQSFAgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gW2V4cGVjdGVkVHlwZV0gLSBDb250ZXh0dWFsIHR5cGUgZm9yIGVtcHR5IFBIUCBhcnJheXMuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtwcmVzZXJ2ZU9wdGlvbmFsXSAtIFdoZXRoZXIgYW4gb3B0aW9uYWwgaWRlbnRpZmllciByZW1haW5zIHdyYXBwZWQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEV4cHJlc3Npb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZXhwZWN0ZWRUeXBlLCBwcmVzZXJ2ZU9wdGlvbmFsID0gZmFsc2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAoZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICBpZiAobm9kZS5raW5kID09IFwibnVsbGtleXdvcmRcIikge1xuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk9wdGlvbmFsTm9uZVwiKSwgbG9jYXRpb259LCB7YWJzZW5jZTogbG9jYXRpb259KVxuICAgIH1cbiAgICBpZiAoa25vd25FeHByZXNzaW9uVHlwZShub2RlLCBjb250ZXh0KT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gY29udmVydEV4cHJlc3Npb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgdW5kZWZpbmVkLCB0cnVlKVxuICAgIH1cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcHRpb25hbFNvbWVcIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIHZhbHVlOiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LCBleHBlY3RlZFR5cGUudmFsdWVUeXBlKVxuICAgIH0sIHtzb21lOiBsb2NhdGlvbn0pXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwibnVsbGtleXdvcmRcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibnVsbCBvdXRzaWRlIGFuIGV4cGxpY2l0IG9wdGlvbmFsIGNvbnRleHRcIiwgbG9jYXRpb24pXG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInZhcmlhYmxlXCIpIHtcbiAgICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKG5vZGUpXG5cbiAgICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyB2YXJpYWJsZVwiLCBsb2NhdGlvbilcbiAgICBpZiAodmFyaWFibGUubmFtZSA9PSBcInRoaXNcIikge1xuICAgICAgaWYgKCFjb250ZXh0LmN1cnJlbnRDbGFzcykgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicmVjZWl2ZXIgb3V0c2lkZSBhIHJlZmVyZW5jZSBjbGFzc1wiLCBsb2NhdGlvbilcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtjbGFzc0lkOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGNvbnRleHQuY3VycmVudENsYXNzLmlkKSxcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVjZWl2ZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbn0sIHtyZWNlaXZlcjogbG9jYXRpb259KVxuICAgIH1cblxuICAgIGNvbnN0IGlkZW50aWZpZXIgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IHZhcmlhYmxlLm5hbWV9LCB7bmFtZTogbG9jYXRpb259KVxuXG4gICAgaWYgKCFwcmVzZXJ2ZU9wdGlvbmFsICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KHZhcmlhYmxlLm5hbWUpPy5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcHRpb25hbFVud3JhcFwiKSwgbG9jYXRpb24sIG9wZXJhbmQ6IGlkZW50aWZpZXJ9LCB7dW53cmFwOiBsb2NhdGlvbn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGlkZW50aWZpZXJcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJudW1iZXJcIikge1xuICAgIGNvbnN0IGxpdGVyYWwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTnVtYmVyfSAqLyAobm9kZSlcbiAgICBjb25zdCB2YWx1ZSA9IE51bWJlcihsaXRlcmFsLnZhbHVlKVxuXG4gICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbi1zYWZlIGludGVnZXIgbGl0ZXJhbFwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJbnRlZ2VyTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJib29sZWFuXCIpIHtcbiAgICBjb25zdCBsaXRlcmFsID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJvb2xlYW59ICovIChub2RlKVxuXG4gICAgaWYgKHR5cGVvZiBsaXRlcmFsLnZhbHVlICE9IFwiYm9vbGVhblwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJpbnZhbGlkIGJvb2xlYW4gbGl0ZXJhbCB2YWx1ZVwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCb29sZWFuTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBsaXRlcmFsLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJzdHJpbmdcIikge1xuICAgIGNvbnN0IGxpdGVyYWwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuU3RyaW5nfSAqLyAobm9kZSlcblxuICAgIGlmICh0eXBlb2YgbGl0ZXJhbC5yYXcgPT0gXCJzdHJpbmdcIiAmJiBsaXRlcmFsLnJhdy5zdGFydHNXaXRoKFwiPDw8XCIpKSB7XG4gICAgICBjb25zdCBkZXRhaWwgPSBsaXRlcmFsLnJhdy5zdGFydHNXaXRoKFwiPDw8J1wiKSA/IFwibm93ZG9jIHN0cmluZ1wiIDogXCJoZXJlZG9jIHN0cmluZ1wiXG5cbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBkZXRhaWwsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAodHlwZW9mIGxpdGVyYWwucmF3ID09IFwic3RyaW5nXCIgJiYgW1wiYlxcXCJcIiwgXCJCXFxcIlwiLCBcImInXCIsIFwiQidcIl0uc29tZSgocHJlZml4KSA9PiBsaXRlcmFsLnJhdy5zdGFydHNXaXRoKHByZWZpeCkpKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJiaW5hcnkgc3RyaW5nIGxpdGVyYWxcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICh0eXBlb2YgbGl0ZXJhbC52YWx1ZSAhPSBcInN0cmluZ1wiIHx8ICFoYXNPbmx5VW5pY29kZVNjYWxhcnMobGl0ZXJhbC52YWx1ZSkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImludmFsaWQgVW5pY29kZSBzdHJpbmcgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiU3RyaW5nTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBsaXRlcmFsLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJlbmNhcHNlZFwiKSB7XG4gICAgY29uc3QgbGl0ZXJhbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FbmNhcHNlZH0gKi8gKG5vZGUpXG4gICAgY29uc3QgZGV0YWlsID0gbGl0ZXJhbC50eXBlID09IFwic3RyaW5nXCIgPyBcImludGVycG9sYXRlZCBzdHJpbmdcIiA6IGAke2xpdGVyYWwudHlwZX0gc3RyaW5nYFxuXG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGRldGFpbCwgbG9jYXRpb24pXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwibm93ZG9jXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vd2RvYyBzdHJpbmdcIiwgbG9jYXRpb24pXG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImFycmF5XCIpIHtcbiAgICBjb25zdCBsaXRlcmFsID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkFycmF5fSAqLyAobm9kZSlcbiAgICBjb25zdCBpbnZhbGlkRW50cnkgPSBsaXRlcmFsLml0ZW1zLmZpbmQoKGVudHJ5KSA9PiB7XG4gICAgICBpZiAoZW50cnkua2luZCAhPSBcImVudHJ5XCIpIHJldHVybiB0cnVlXG4gICAgICBjb25zdCBjYW5kaWRhdGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRW50cnl9ICovIChlbnRyeSlcblxuICAgICAgcmV0dXJuIGNhbmRpZGF0ZS5ieVJlZiB8fCBjYW5kaWRhdGUudW5wYWNrXG4gICAgfSlcblxuICAgIGlmIChpbnZhbGlkRW50cnkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImFycmF5IHJlZmVyZW5jZSBvciB1bnBhY2tpbmdcIiwgbm9kZUxvY2F0aW9uKGludmFsaWRFbnRyeSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgY29uc3QgZW50cmllcyA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FbnRyeVtdfSAqLyAobGl0ZXJhbC5pdGVtcylcbiAgICBjb25zdCBoYXNLZXlzID0gZW50cmllcy5zb21lKChlbnRyeSkgPT4gZW50cnkua2V5ICE9IG51bGwpXG4gICAgY29uc3QgaGFzSW1wbGljaXQgPSBlbnRyaWVzLnNvbWUoKGVudHJ5KSA9PiBlbnRyeS5rZXkgPT0gbnVsbClcbiAgICBjb25zdCBjb2xsZWN0aW9uS2luZCA9IGVudHJpZXMubGVuZ3RoID09IDAgPyBleHBlY3RlZFR5cGU/LmtpbmQgOiBoYXNLZXlzICYmICFoYXNJbXBsaWNpdFxuICAgICAgPyBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJPcmRlcmVkTWFwVHlwZVwiIDogXCJNYXBUeXBlXCJcbiAgICAgIDogIWhhc0tleXMgPyBcIkxpc3RUeXBlXCIgOiBcIm1peGVkXCJcblxuICAgIGlmIChjb2xsZWN0aW9uS2luZCA9PSBcIm1peGVkXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1peGVkIGxpc3QvbWFwIGFycmF5IGxpdGVyYWxcIiwgbG9jYXRpb24pXG4gICAgaWYgKGNvbGxlY3Rpb25LaW5kID09IFwiTGlzdFR5cGVcIikge1xuICAgICAgY29uc3QgZWxlbWVudFR5cGUgPSBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJMaXN0VHlwZVwiID8gZXhwZWN0ZWRUeXBlLmVsZW1lbnRUeXBlIDogdW5kZWZpbmVkXG5cbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAgZWxlbWVudHM6IGVudHJpZXMubWFwKChlbnRyeSkgPT4gY29udmVydEV4cHJlc3Npb24oZW50cnkudmFsdWUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGVsZW1lbnRUeXBlKSksXG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxpc3RMaXRlcmFsXCIpLFxuICAgICAgICBsb2NhdGlvblxuICAgICAgfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKGNvbGxlY3Rpb25LaW5kID09IFwiTWFwVHlwZVwiIHx8IGNvbGxlY3Rpb25LaW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgICAgY29uc3QgdmFsdWVUeXBlID0gZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiTWFwVHlwZVwiIHx8IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCJcbiAgICAgICAgPyBleHBlY3RlZFR5cGUudmFsdWVUeXBlIDogdW5kZWZpbmVkXG4gICAgICBjb25zdCBzZW1hbnRpY0VudHJpZXMgPSBlbnRyaWVzLm1hcCgoZW50cnkpID0+IHtcbiAgICAgICAgaWYgKCFlbnRyeS5rZXkgfHwgZW50cnkua2V5LmtpbmQgIT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1hcCBrZXkgb3RoZXIgdGhhbiBhIGxpdGVyYWwgc3RyaW5nXCIsIGVudHJ5LmtleSA/IG5vZGVMb2NhdGlvbihlbnRyeS5rZXksIGZpbGVuYW1lLCBzb3VyY2UpIDogbm9kZUxvY2F0aW9uKGVudHJ5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBrZXkgPSBjb252ZXJ0RXhwcmVzc2lvbihlbnRyeS5rZXksIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG5cbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICAgIGtleTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdHJpbmdMaXRlcmFsfSAqLyAoa2V5KSxcbiAgICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNYXBFbnRyeVwiKSxcbiAgICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKGVudHJ5LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgICB2YWx1ZTogY29udmVydEV4cHJlc3Npb24oZW50cnkudmFsdWUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHZhbHVlVHlwZSlcbiAgICAgICAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiPT5cIiwgZW50cnkua2V5LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBlbnRyeS52YWx1ZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGVudHJpZXM6IHNlbWFudGljRW50cmllcyxcbiAgICAgICAga2luZDogY29sbGVjdGlvbktpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiXG4gICAgICAgICAgPyAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKVxuICAgICAgICAgIDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTWFwTGl0ZXJhbFwiKSxcbiAgICAgICAgbG9jYXRpb25cbiAgICAgIH0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZW1wdHkgYXJyYXkgd2l0aG91dCBhIGxpc3Qgb3IgbWFwIHR5cGVcIiwgbG9jYXRpb24pXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwibmV3XCIpIHtcbiAgICBjb25zdCBjb25zdHJ1Y3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTmV3fSAqLyAobm9kZSlcbiAgICBjb25zdCBuYW1lID0gY29uc3RydWN0aW9uLndoYXQua2luZCA9PSBcIm5hbWVcIiA/IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lfSAqLyAoY29uc3RydWN0aW9uLndoYXQpIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoIW5hbWUgfHwgbmFtZS5yZXNvbHV0aW9uICE9IFwidXFuXCIgfHwgdHlwZW9mIG5hbWUubmFtZSAhPSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkeW5hbWljIG9yIHF1YWxpZmllZCByZWNvcmQgY29uc3RydWN0aW9uXCIsIG5vZGVMb2NhdGlvbihjb25zdHJ1Y3Rpb24ud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gY29udGV4dC5yZWNvcmROYW1lcy5nZXQobmFtZS5uYW1lKVxuXG4gICAgaWYgKCFkZWNsYXJhdGlvbikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiY29uc3RydWN0aW9uIG9mIGFuIHVua25vd24gbm9taW5hbCBjbGFzc1wiLCBub2RlTG9jYXRpb24oY29uc3RydWN0aW9uLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGlmIChkZWNsYXJhdGlvbi5raW5kID09IFwiQ2xhc3NEZWNsYXJhdGlvblwiKSB7XG4gICAgICBjb25zdCB1bnN1cHBvcnRlZEFyZ3VtZW50ID0gY29uc3RydWN0aW9uLmFyZ3VtZW50cy5maW5kKChhcmd1bWVudCkgPT5cbiAgICAgICAgYXJndW1lbnQua2luZCA9PSBcIm5hbWVkYXJndW1lbnRcIiB8fCBhcmd1bWVudC5raW5kID09IFwidmFyaWFkaWNcIiB8fCBSZWZsZWN0LmdldChhcmd1bWVudCwgXCJieXJlZlwiKSA9PT0gdHJ1ZSlcblxuICAgICAgaWYgKHVuc3VwcG9ydGVkQXJndW1lbnQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbi1wb3NpdGlvbmFsIHJlZmVyZW5jZSBjb25zdHJ1Y3RvciBhcmd1bWVudFwiLFxuICAgICAgICBub2RlTG9jYXRpb24odW5zdXBwb3J0ZWRBcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBjb25zdCBjbGFzc0xvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGNvbnN0cnVjdGlvbi53aGF0LCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7YXJndW1lbnRzOiBjb25zdHJ1Y3Rpb24uYXJndW1lbnRzLm1hcCgoYXJndW1lbnQsIGluZGV4KSA9PlxuICAgICAgICBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZGVjbGFyYXRpb24uY29uc3RydWN0b3IucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUpKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlJlZmVyZW5jZUNvbnN0cnVjdGlvblwiKSwgbG9jYXRpb24sXG4gICAgICByZWZlcmVuY2U6IHJlZmVyZW5jZVR5cGUoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGNsYXNzTG9jYXRpb24pfSwge2NsYXNzOiBjbGFzc0xvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKGRlY2xhcmF0aW9uLmtpbmQgPT0gXCJFZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm93bmVkIHJlc291cmNlIGNvbnN0cnVjdGlvblwiLCBub2RlTG9jYXRpb24oY29uc3RydWN0aW9uLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgY29udGV4dHVhbFR5cGVBcmd1bWVudHMgPSBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIgJiYgZXhwZWN0ZWRUeXBlLmRlY2xhcmF0aW9uSWQgPT0gZGVjbGFyYXRpb24uaWRcbiAgICAgID8gZXhwZWN0ZWRUeXBlLmFyZ3VtZW50c1xuICAgICAgOiB1bmRlZmluZWRcbiAgICBjb25zdCB2aXNpYmxlVHlwZVBhcmFtZXRlcklkcyA9IG5ldyBTZXQoWy4uLmNvbnRleHQudHlwZVBhcmFtZXRlcnM/LnZhbHVlcygpID8/IFtdXVxuICAgICAgLm1hcCgocGFyYW1ldGVyKSA9PiAvKiogQHR5cGUge3N0cmluZ30gKi8gKHBhcmFtZXRlci5pZCkpKVxuICAgIGNvbnN0IHR5cGVBcmd1bWVudHMgPSBjb250ZXh0dWFsVHlwZUFyZ3VtZW50cyAmJlxuICAgICAgIWNvbnRleHR1YWxUeXBlQXJndW1lbnRzLnNvbWUoKGFyZ3VtZW50KSA9PiB0eXBlQ29udGFpbnNBbnlWYXJpYWJsZShhcmd1bWVudCwgdmlzaWJsZVR5cGVQYXJhbWV0ZXJJZHMpKVxuICAgICAgPyBjb250ZXh0dWFsVHlwZUFyZ3VtZW50c1xuICAgICAgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGFyZ3VtZW50czogY29uc3RydWN0aW9uLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50LCBpbmRleCkgPT5cbiAgICAgICAgY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsXG4gICAgICAgICAgaW5zdGFudGlhdGVkUmVjb3JkRmllbGRUeXBlKGRlY2xhcmF0aW9uLCB0eXBlQXJndW1lbnRzLCBpbmRleCkpKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlJlY29yZENvbnN0cnVjdGlvblwiKSxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgcmVjb3JkOiByZWNvcmRUeXBlKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBub2RlTG9jYXRpb24oY29uc3RydWN0aW9uLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICB0eXBlQXJndW1lbnRzKVxuICAgIH0sIHtyZWNvcmQ6IG5vZGVMb2NhdGlvbihjb25zdHJ1Y3Rpb24ud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcInByb3BlcnR5bG9va3VwXCIpIHtcbiAgICBjb25zdCByZWFkID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAobm9kZSlcbiAgICBjb25zdCBvZmZzZXQgPSByZWFkLm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChyZWFkLm9mZnNldCkgOiB1bmRlZmluZWRcblxuICAgIGlmICghb2Zmc2V0IHx8IHR5cGVvZiBvZmZzZXQubmFtZSAhPSBcInN0cmluZ1wiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkeW5hbWljIG9yIGNvbXB1dGVkIG1lbWJlciBhY2Nlc3NcIiwgbm9kZUxvY2F0aW9uKHJlYWQub2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgaWYgKHJlYWQud2hhdC5raW5kID09IFwidmFyaWFibGVcIiAmJiAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChyZWFkLndoYXQpLm5hbWUgPT0gXCJ0aGlzXCIgJiZcbiAgICAgIGNvbnRleHQuY3VycmVudENsYXNzKSB7XG4gICAgICBjb25zdCBmaWVsZCA9IGNvbnRleHQuY3VycmVudENsYXNzLmZpZWxkcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5uYW1lID09IG9mZnNldC5uYW1lKVxuXG4gICAgICBpZiAoIWZpZWxkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYHVua25vd24gcHJpdmF0ZSBmaWVsZCAnJHtvZmZzZXQubmFtZX0nYCwgbm9kZUxvY2F0aW9uKG9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7ZmllbGQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmllbGQuaWQpLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQcml2YXRlRmllbGRSZWFkXCIpLCBsb2NhdGlvbixcbiAgICAgICAgcmVjZWl2ZXI6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjZWl2ZXJFeHByZXNzaW9ufSAqLyAoXG4gICAgICAgICAgY29udmVydEV4cHJlc3Npb24ocmVhZC53aGF0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSl9LCB7bWVtYmVyOiBub2RlTG9jYXRpb24ob2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgfVxuICAgIGNvbnN0IHJlY2VpdmVyVHlwZSA9IGtub3duRXhwcmVzc2lvblR5cGUocmVhZC53aGF0LCBjb250ZXh0KVxuICAgIGlmIChyZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInByaXZhdGUgcmVmZXJlbmNlLWNsYXNzIGZpZWxkIGFjY2Vzc1wiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgcmVjZWl2ZXJSZWNvcmQgPSByZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIiA/IHJlY2VpdmVyVHlwZS52YWx1ZVR5cGUgOiByZWNlaXZlclR5cGVcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IHJlY2VpdmVyUmVjb3JkPy5raW5kID09IFwiUmVjb3JkVHlwZVwiID8gY29udGV4dC5yZWNvcmRzLmdldChyZWNlaXZlclJlY29yZC5kZWNsYXJhdGlvbklkKSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKChkZWNsYXJhdGlvbj8udHlwZVBhcmFtZXRlcnM/Lmxlbmd0aCA/PyAwKSA+IDApIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImdlbmVyaWMgcmVjb3JkIHByb3BlcnR5IGFjY2Vzc1wiLCBub2RlTG9jYXRpb24ocmVhZC5vZmZzZXQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBmaWVsZDogb2Zmc2V0Lm5hbWUsXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNZW1iZXJSZWFkXCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByZWNlaXZlcjogY29udmVydEV4cHJlc3Npb24ocmVhZC53aGF0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgIH0sIHttZW1iZXI6IG5vZGVMb2NhdGlvbihyZWFkLm9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcIm9mZnNldGxvb2t1cFwiKSB7XG4gICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk9mZnNldExvb2t1cH0gKi8gKG5vZGUpXG5cbiAgICBpZiAoIWxvb2t1cC5vZmZzZXQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImFwcGVuZCBvciBtaXNzaW5nIGFycmF5IGluZGV4XCIsIGxvY2F0aW9uKVxuICAgIGNvbnN0IHJlY2VpdmVyID0gbG9va3VwLndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCByZWNlaXZlclR5cGUgPSByZWNlaXZlciAmJiB0eXBlb2YgcmVjZWl2ZXIubmFtZSA9PSBcInN0cmluZ1wiID8gY29udGV4dC5iaW5kaW5ncy5nZXQocmVjZWl2ZXIubmFtZSkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBhY2Nlc3NLaW5kID0gcmVjZWl2ZXJUeXBlPy5raW5kID09IFwiTGlzdFR5cGVcIiA/IFwibGlzdFwiIDpcbiAgICAgIHJlY2VpdmVyVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIiB8fCByZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiID8gXCJtYXBcIiA6XG4gICAgICBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJudW1iZXJcIiA/IFwibGlzdFwiIDogbG9va3VwLm9mZnNldC5raW5kID09IFwic3RyaW5nXCIgPyBcIm1hcFwiIDogdW5kZWZpbmVkXG5cbiAgICBpZiAoYWNjZXNzS2luZCA9PSBcImxpc3RcIiAmJiBbXCJudW1iZXJcIiwgXCJzdHJpbmdcIiwgXCJ2YXJpYWJsZVwiXS5pbmNsdWRlcyhsb29rdXAub2Zmc2V0LmtpbmQpKSB7XG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgIGNvbGxlY3Rpb246IGNvbnZlcnRFeHByZXNzaW9uKGxvb2t1cC53aGF0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICAgICAgaW5kZXg6IGNvbnZlcnRFeHByZXNzaW9uKGxvb2t1cC5vZmZzZXQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJMaXN0SW5kZXhFeHByZXNzaW9uXCIpLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgdG90YWxpdHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInByb3ZlblwiKVxuICAgICAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiW1wiLCBsb29rdXAud2hhdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgbG9va3VwLm9mZnNldC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgfVxuICAgIGlmIChhY2Nlc3NLaW5kID09IFwibWFwXCIgJiYgW1wibnVtYmVyXCIsIFwic3RyaW5nXCIsIFwidmFyaWFibGVcIl0uaW5jbHVkZXMobG9va3VwLm9mZnNldC5raW5kKSkge1xuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBjb2xsZWN0aW9uOiBjb252ZXJ0RXhwcmVzc2lvbihsb29rdXAud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksXG4gICAgICAgIGtleTogY29udmVydEV4cHJlc3Npb24obG9va3VwLm9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksXG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1hcExvb2t1cEV4cHJlc3Npb25cIiksXG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICB0b3RhbGl0eTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwicHJvdmVuXCIpXG4gICAgICB9LCB7b3BlcmF0b3I6IHRva2VuTG9jYXRpb24oXCJbXCIsIGxvb2t1cC53aGF0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBsb29rdXAub2Zmc2V0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG5cbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJub25saXRlcmFsIGFycmF5IGFjY2Vzc1wiLCBub2RlTG9jYXRpb24obG9va3VwLm9mZnNldCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICBpZiAobm9kZS5raW5kID09IFwidW5hcnlcIikge1xuICAgIGNvbnN0IHVuYXJ5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlVuYXJ5fSAqLyAobm9kZSlcblxuICAgIGlmICghW1wiIVwiLCBcIi1cIl0uaW5jbHVkZXModW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgdW5hcnkgJHt1bmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiVW5hcnlFeHByZXNzaW9uXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG9wZXJhbmQ6IGNvbnZlcnRFeHByZXNzaW9uKHVuYXJ5LndoYXQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24odW5hcnkudHlwZSwgdW5hcnkubG9jPy5zdGFydC5vZmZzZXQgPz8gMCwgdW5hcnkud2hhdC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyB1bmFyeS5sb2M/LmVuZC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KSwgdW5hcnkudHlwZSA9PSBcIiFcIiA/IFwiTm90XCIgOiBcIk5lZ2F0ZVwiKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHNlbWFudGljKSlcbiAgfVxuXG4gIGlmIChub2RlLmtpbmQgPT0gXCJiaW5cIikge1xuICAgIGNvbnN0IGJpbmFyeSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CaW59ICovIChub2RlKVxuICAgIGlmIChiaW5hcnkudHlwZSA9PSBcIiE9PVwiICYmIGJpbmFyeS5sZWZ0LmtpbmQgPT0gXCJ2YXJpYWJsZVwiICYmIGJpbmFyeS5yaWdodC5raW5kID09IFwibnVsbGtleXdvcmRcIikge1xuICAgICAgY29uc3Qgb3BlcmFuZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWRlbnRpZmllckV4cHJlc3Npb259ICovIChcbiAgICAgICAgY29udmVydEV4cHJlc3Npb24oYmluYXJ5LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICAgIClcblxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk9wdGlvbmFsSXNQcmVzZW50XCIpLCBsb2NhdGlvbiwgb3BlcmFuZH0sIHtcbiAgICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oYmluYXJ5LnR5cGUsIGJpbmFyeS5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBiaW5hcnkucmlnaHQubG9jPy5zdGFydC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIH0pXG4gICAgfVxuICAgIGlmIChbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKGJpbmFyeS50eXBlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBjb2VyY2l2ZSBlcXVhbGl0eSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmIChbXCJhbmRcIiwgXCJvclwiXS5pbmNsdWRlcyhiaW5hcnkudHlwZSkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBgcHJlY2VkZW5jZS1zZW5zaXRpdmUgYm9vbGVhbiAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuICAgIGlmICghcGhwQmluYXJ5T3BlcmF0aW9ucy5oYXMoYmluYXJ5LnR5cGUpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYGJpbmFyeSAke2JpbmFyeS50eXBlfWAsIGxvY2F0aW9uKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCaW5hcnlFeHByZXNzaW9uXCIpLFxuICAgICAgbGVmdDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByaWdodDogY29udmVydEV4cHJlc3Npb24oYmluYXJ5LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgIH0sIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChwaHBCaW5hcnlPcGVyYXRpb25zLmdldChiaW5hcnkudHlwZSkpKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHdpdGhQYXJzZXJSYW5nZXMoc2VtYW50aWMsIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKGJpbmFyeS50eXBlLCBiaW5hcnkubGVmdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgYmluYXJ5LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSkpKVxuICB9XG5cbiAgaWYgKG5vZGUua2luZCA9PSBcImNhbGxcIikge1xuICAgIGNvbnN0IGNhbGwgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2FsbH0gKi8gKG5vZGUpXG5cbiAgICBpZiAoY2FsbC53aGF0LmtpbmQgPT0gXCJwcm9wZXJ0eWxvb2t1cFwiKSB7XG4gICAgICBjb25zdCBsb29rdXAgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUHJvcGVydHlMb29rdXB9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChjYWxsLndoYXQpKVxuICAgICAgY29uc3QgbWVtYmVyID0gbG9va3VwLm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChsb29rdXAub2Zmc2V0KSA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgcmVjZWl2ZXJUeXBlID0ga25vd25FeHByZXNzaW9uVHlwZShsb29rdXAud2hhdCwgY29udGV4dClcblxuICAgICAgaWYgKG1lbWJlciAmJiB0eXBlb2YgbWVtYmVyLm5hbWUgPT0gXCJzdHJpbmdcIiAmJiByZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgICAgY29uc3QgbWV0aG9kID0gY29udGV4dC5jbGFzc2VzLmdldChyZWNlaXZlclR5cGUuZGVjbGFyYXRpb25JZCk/Lm1ldGhvZHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PSBtZW1iZXIubmFtZSlcbiAgICAgICAgY29uc3QgdW5zdXBwb3J0ZWRBcmd1bWVudCA9IGNhbGwuYXJndW1lbnRzLmZpbmQoKGFyZ3VtZW50KSA9PlxuICAgICAgICAgIGFyZ3VtZW50LmtpbmQgPT0gXCJuYW1lZGFyZ3VtZW50XCIgfHwgYXJndW1lbnQua2luZCA9PSBcInZhcmlhZGljXCIgfHwgUmVmbGVjdC5nZXQoYXJndW1lbnQsIFwiYnlyZWZcIikgPT09IHRydWUpXG5cbiAgICAgICAgaWYgKHVuc3VwcG9ydGVkQXJndW1lbnQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbi1wb3NpdGlvbmFsIG1ldGhvZCBhcmd1bWVudFwiLFxuICAgICAgICAgIG5vZGVMb2NhdGlvbih1bnN1cHBvcnRlZEFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2FyZ3VtZW50czogY2FsbC5hcmd1bWVudHMubWFwKChhcmd1bWVudCwgaW5kZXgpID0+XG4gICAgICAgICAgY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIG1ldGhvZD8ucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUpKSxcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTWV0aG9kQ2FsbEV4cHJlc3Npb25cIiksIGxvY2F0aW9uLCBtZXRob2Q6IG1ldGhvZD8uaWQgPz8gbWVtYmVyLm5hbWUsXG4gICAgICAgIHJlY2VpdmVyOiBjb252ZXJ0RXhwcmVzc2lvbihsb29rdXAud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCl9LCB7bWVtYmVyOiBub2RlTG9jYXRpb24obWVtYmVyLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNhbGwud2hhdC5raW5kID09IFwicHJvcGVydHlsb29rdXBcIiAmJiBjYWxsLmFyZ3VtZW50cy5sZW5ndGggPT0gMCkge1xuICAgICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoY2FsbC53aGF0KSlcbiAgICAgIGNvbnN0IHJlY2VpdmVyID0gbG9va3VwLndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IG1lbWJlciA9IGxvb2t1cC5vZmZzZXQua2luZCA9PSBcImlkZW50aWZpZXJcIiA/IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAobG9va3VwLm9mZnNldCkgOiB1bmRlZmluZWRcblxuICAgICAgaWYgKHJlY2VpdmVyICYmIHR5cGVvZiByZWNlaXZlci5uYW1lID09IFwic3RyaW5nXCIgJiYgbWVtYmVyPy5uYW1lID09IFwiZ2V0TWVzc2FnZVwiICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KHJlY2VpdmVyLm5hbWUpPy5raW5kID09IFwiRXJyb3JUeXBlXCIpIHtcbiAgICAgICAgY29uc3QgcmVjZWl2ZXJMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihyZWNlaXZlciwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JNZXNzYWdlUmVhZFwiKSxcbiAgICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgICByZWNlaXZlcjogd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiksIGxvY2F0aW9uOiByZWNlaXZlckxvY2F0aW9uLCBuYW1lOiByZWNlaXZlci5uYW1lfSwge1xuICAgICAgICAgICAgbmFtZTogcmVjZWl2ZXJMb2NhdGlvblxuICAgICAgICAgIH0pXG4gICAgICAgIH0sIHttZW1iZXI6IG5vZGVMb2NhdGlvbihtZW1iZXIsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICAgIH1cbiAgICAgIGlmIChtZW1iZXIgJiYgdHlwZW9mIG1lbWJlci5uYW1lID09IFwic3RyaW5nXCIgJiYga25vd25HZW5lcmljUmVjb3JkQWNjZXNzb3JUeXBlKGxvb2t1cCwgY29udGV4dCkpIHtcbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICAgIGZpZWxkOiBtZW1iZXIubmFtZSxcbiAgICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNZW1iZXJSZWFkXCIpLFxuICAgICAgICAgIGxvY2F0aW9uLFxuICAgICAgICAgIHJlY2VpdmVyOiBjb252ZXJ0RXhwcmVzc2lvbihsb29rdXAud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICAgICAgfSwge21lbWJlcjogbm9kZUxvY2F0aW9uKG1lbWJlciwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChjYWxsLndoYXQua2luZCA9PSBcIm5hbWVcIiAmJiBjYWxsLndoYXQubmFtZSA9PSBcImNvdW50XCIgJiYgY2FsbC5hcmd1bWVudHMubGVuZ3RoID09IDEpIHtcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAgY29sbGVjdGlvbjogY29udmVydEV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0sIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDb2xsZWN0aW9uU2l6ZUV4cHJlc3Npb25cIiksXG4gICAgICAgIGxvY2F0aW9uXG4gICAgICB9LCB7b3BlcmF0b3I6IG5vZGVMb2NhdGlvbihjYWxsLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG5cbiAgICBpZiAoY2FsbC53aGF0LmtpbmQgIT0gXCJuYW1lXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImR5bmFtaWMgY2FsbFwiLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgY2FsbGVkTmFtZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lfSAqLyAoY2FsbC53aGF0KVxuXG4gICAgaWYgKGNhbGxlZE5hbWUucmVzb2x1dGlvbiAhPSBcInVxblwiIHx8IGNhbGxlZE5hbWUubmFtZS5pbmNsdWRlcyhcIlxcXFxcIikpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInF1YWxpZmllZCBjYWxsXCIsIG5vZGVMb2NhdGlvbihjYWxsLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBjb25zdCB1bnN1cHBvcnRlZEFyZ3VtZW50ID0gY2FsbC5hcmd1bWVudHMuZmluZCgoYXJndW1lbnQpID0+XG4gICAgICBhcmd1bWVudC5raW5kID09IFwibmFtZWRhcmd1bWVudFwiIHx8IGFyZ3VtZW50LmtpbmQgPT0gXCJ2YXJpYWRpY1wiIHx8IFJlZmxlY3QuZ2V0KGFyZ3VtZW50LCBcImJ5cmVmXCIpID09PSB0cnVlKVxuXG4gICAgaWYgKHVuc3VwcG9ydGVkQXJndW1lbnQpIHtcbiAgICAgIGNvbnN0IGRldGFpbCA9IHVuc3VwcG9ydGVkQXJndW1lbnQua2luZCA9PSBcIm5hbWVkYXJndW1lbnRcIiA/IFwibmFtZWQgYXJndW1lbnRcIiA6XG4gICAgICAgIHVuc3VwcG9ydGVkQXJndW1lbnQua2luZCA9PSBcInZhcmlhZGljXCIgPyBcInVucGFja2VkIGFyZ3VtZW50XCIgOiBcImJ5LXJlZmVyZW5jZSBhcmd1bWVudFwiXG5cbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBkZXRhaWwsIG5vZGVMb2NhdGlvbih1bnN1cHBvcnRlZEFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG5cbiAgICBjb25zdCBjYWxsZWUgPSBjYWxsZWROYW1lLm5hbWVcblxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGNvbnRleHQuZnVuY3Rpb25zLmdldChjYWxsZWUpXG4gICAgY29uc3Qga25vd25Bcmd1bWVudHMgPSBjYWxsLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50KSA9PiBrbm93bkNhbGxBcmd1bWVudFR5cGUoYXJndW1lbnQsIGNvbnRleHQpKVxuICAgIGNvbnN0IHBhcmFtZXRlclR5cGVzID0gc2lnbmF0dXJlID8ga25vd25DYWxsUGFyYW1ldGVyVHlwZXMoc2lnbmF0dXJlLCBrbm93bkFyZ3VtZW50cykgOiB1bmRlZmluZWRcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGFyZ3VtZW50czogY2FsbC5hcmd1bWVudHMubWFwKChhcmd1bWVudCwgaW5kZXgpID0+XG4gICAgICAgIGNvbnZlcnRFeHByZXNzaW9uKGFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LFxuICAgICAgICAgIHBhcmFtZXRlclR5cGVzPy5baW5kZXhdID8/IHNpZ25hdHVyZT8ucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUsXG4gICAgICAgICAgcHJlc2VydmVzR2VuZXJpY09wdGlvbmFsRXZpZGVuY2Uoc2lnbmF0dXJlLCBpbmRleCkpKSxcbiAgICAgIGNhbGxlZSxcbiAgICAgIGtpbmQ6IFwiQ2FsbEV4cHJlc3Npb25cIixcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2NhbGxlZTogbm9kZUxvY2F0aW9uKGNhbGwud2hhdCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9XG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIG5vZGUua2luZCwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgb25seSByZXN1bHQgdHlwZXMgZXN0YWJsaXNoZWQgYnkgZXhwbGljaXQgc2lnbmF0dXJlcyBhbmQgYmluZGluZ3MuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBhcnNlci1vd25lZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yVHlwZSB8IHVuZGVmaW5lZH0gS25vd24gcmVzdWx0IHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGtub3duRXhwcmVzc2lvblR5cGUobm9kZSwgY29udGV4dCkge1xuICBpZiAobm9kZS5raW5kID09IFwidmFyaWFibGVcIikge1xuICAgIGNvbnN0IHZhcmlhYmxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAobm9kZSlcblxuICAgIGlmICh2YXJpYWJsZS5uYW1lID09IFwidGhpc1wiICYmIGNvbnRleHQuY3VycmVudENsYXNzPy5pZCkge1xuICAgICAgcmV0dXJuIHtkZWNsYXJhdGlvbklkOiBjb250ZXh0LmN1cnJlbnRDbGFzcy5pZCwga2luZDogXCJSZWZlcmVuY2VUeXBlXCJ9XG4gICAgfVxuICAgIGlmICh0eXBlb2YgdmFyaWFibGUubmFtZSA9PSBcInN0cmluZ1wiKSByZXR1cm4gY29udGV4dC5iaW5kaW5ncy5nZXQodmFyaWFibGUubmFtZSlcbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwiY2FsbFwiKSB7XG4gICAgY29uc3QgY2FsbCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5DYWxsfSAqLyAobm9kZSlcbiAgICBjb25zdCBuYW1lID0gY2FsbC53aGF0LmtpbmQgPT0gXCJuYW1lXCIgJiYgdHlwZW9mIGNhbGwud2hhdC5uYW1lID09IFwic3RyaW5nXCIgPyBjYWxsLndoYXQubmFtZSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5hbWUpIHtcbiAgICAgIGNvbnN0IHNpZ25hdHVyZSA9IGNvbnRleHQuZnVuY3Rpb25zLmdldChuYW1lKVxuXG4gICAgICBpZiAoc2lnbmF0dXJlKSByZXR1cm4ga25vd25DYWxsUmV0dXJuVHlwZShzaWduYXR1cmUsIGNhbGwuYXJndW1lbnRzLm1hcCgoYXJndW1lbnQpID0+IGtub3duRXhwcmVzc2lvblR5cGUoYXJndW1lbnQsIGNvbnRleHQpKSlcbiAgICB9XG4gICAgaWYgKGNhbGwud2hhdC5raW5kID09IFwicHJvcGVydHlsb29rdXBcIiAmJiBjYWxsLmFyZ3VtZW50cy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIGtub3duR2VuZXJpY1JlY29yZEFjY2Vzc29yVHlwZShcbiAgICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoY2FsbC53aGF0KSksIGNvbnRleHQpXG4gICAgfVxuICAgIGlmIChjYWxsLndoYXQua2luZCA9PSBcInByb3BlcnR5bG9va3VwXCIpIHtcbiAgICAgIGNvbnN0IGxvb2t1cCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Qcm9wZXJ0eUxvb2t1cH0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGNhbGwud2hhdCkpXG4gICAgICBjb25zdCByZWNlaXZlciA9IGtub3duRXhwcmVzc2lvblR5cGUobG9va3VwLndoYXQsIGNvbnRleHQpXG4gICAgICBjb25zdCBtZW1iZXIgPSBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGxvb2t1cC5vZmZzZXQpIDogdW5kZWZpbmVkXG5cbiAgICAgIGlmIChyZWNlaXZlcj8ua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIiAmJiBtZW1iZXIgJiYgdHlwZW9mIG1lbWJlci5uYW1lID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgcmV0dXJuIGNvbnRleHQuY2xhc3Nlcy5nZXQocmVjZWl2ZXIuZGVjbGFyYXRpb25JZCk/Lm1ldGhvZHMuZmluZCgobWV0aG9kKSA9PiBtZXRob2QubmFtZSA9PSBtZW1iZXIubmFtZSk/LnJldHVyblR5cGVcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgaWYgKG5vZGUua2luZCA9PSBcIm9mZnNldGxvb2t1cFwiKSB7XG4gICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk9mZnNldExvb2t1cH0gKi8gKG5vZGUpXG4gICAgY29uc3QgY29sbGVjdGlvblR5cGUgPSBrbm93bkV4cHJlc3Npb25UeXBlKGxvb2t1cC53aGF0LCBjb250ZXh0KVxuXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiTGlzdFR5cGVcIikgcmV0dXJuIGNvbGxlY3Rpb25UeXBlLmVsZW1lbnRUeXBlXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiTWFwVHlwZVwiIHx8IGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiT3JkZXJlZE1hcFR5cGVcIikgcmV0dXJuIGNvbGxlY3Rpb25UeXBlLnZhbHVlVHlwZVxuICB9XG4gIGlmIChub2RlLmtpbmQgPT0gXCJuZXdcIikge1xuICAgIGNvbnN0IGNvbnN0cnVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OZXd9ICovIChub2RlKVxuICAgIGNvbnN0IG5hbWUgPSBjb25zdHJ1Y3Rpb24ud2hhdC5raW5kID09IFwibmFtZVwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWV9ICovIChjb25zdHJ1Y3Rpb24ud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IG5hbWUgJiYgdHlwZW9mIG5hbWUubmFtZSA9PSBcInN0cmluZ1wiID8gY29udGV4dC5yZWNvcmROYW1lcy5nZXQobmFtZS5uYW1lKSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKGRlY2xhcmF0aW9uPy5pZCkgcmV0dXJuIGRlY2xhcmF0aW9uLmtpbmQgPT0gXCJDbGFzc0RlY2xhcmF0aW9uXCJcbiAgICAgID8ge2RlY2xhcmF0aW9uSWQ6IGRlY2xhcmF0aW9uLmlkLCBraW5kOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgICAgIDoge2RlY2xhcmF0aW9uSWQ6IGRlY2xhcmF0aW9uLmlkLCBraW5kOiBcIlJlY29yZFR5cGVcIn1cbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwicHJvcGVydHlsb29rdXBcIikge1xuICAgIGNvbnN0IHJlYWQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUHJvcGVydHlMb29rdXB9ICovIChub2RlKVxuICAgIGNvbnN0IHJlY2VpdmVyID0ga25vd25FeHByZXNzaW9uVHlwZShyZWFkLndoYXQsIGNvbnRleHQpXG5cbiAgICBpZiAocmVhZC53aGF0LmtpbmQgPT0gXCJ2YXJpYWJsZVwiICYmIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKHJlYWQud2hhdCkubmFtZSA9PSBcInRoaXNcIiAmJlxuICAgICAgY29udGV4dC5jdXJyZW50Q2xhc3MpIHtcbiAgICAgIGNvbnN0IG9mZnNldCA9IHJlYWQub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKHJlYWQub2Zmc2V0KSA6IHVuZGVmaW5lZFxuXG4gICAgICByZXR1cm4gY29udGV4dC5jdXJyZW50Q2xhc3MuZmllbGRzLmZpbmQoKGZpZWxkKSA9PiBmaWVsZC5uYW1lID09IG9mZnNldD8ubmFtZSk/LnR5cGVcbiAgICB9XG5cbiAgICBpZiAocmVjZWl2ZXI/LmtpbmQgIT0gXCJSZWNvcmRUeXBlXCIpIHJldHVybiB1bmRlZmluZWRcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGNvbnRleHQucmVjb3Jkcy5nZXQocmVjZWl2ZXIuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCBvZmZzZXQgPSByZWFkLm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChyZWFkLm9mZnNldCkgOiB1bmRlZmluZWRcblxuICAgIGNvbnN0IG1lbWJlck5hbWUgPSBvZmZzZXQgJiYgdHlwZW9mIG9mZnNldC5uYW1lID09IFwic3RyaW5nXCIgPyBvZmZzZXQubmFtZSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG1lbWJlck5hbWUgJiYgZGVjbGFyYXRpb24pIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gZGVjbGFyYXRpb24uZmllbGRzLmZpbmRJbmRleCgoZmllbGQpID0+IGZpZWxkLm5hbWUgPT0gbWVtYmVyTmFtZSlcblxuICAgICAgcmV0dXJuIGluc3RhbnRpYXRlZFJlY29yZEZpZWxkVHlwZShkZWNsYXJhdGlvbiwgcmVjZWl2ZXIuYXJndW1lbnRzLCBpbmRleClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkXG59XG5cbi8qKlxuICogUmVzb2x2ZXMgZXhhY3QgcGFyc2VyLWtub3duIGFyZ3VtZW50IGV2aWRlbmNlIHdpdGhvdXQgY2hhbmdpbmcgdGhlIGVzdGFibGlzaGVkXG4gKiBleHByZXNzaW9uLXJlc3VsdCBjbGFzc2lmaWVyIHVzZWQgZm9yIG9wdGlvbmFsIGNvbnZlcnNpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBhcnNlci1vd25lZCBjYWxsIGFyZ3VtZW50LlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yVHlwZSB8IHVuZGVmaW5lZH0gS25vd24gYXJndW1lbnQgdHlwZS5cbiAqL1xuZnVuY3Rpb24ga25vd25DYWxsQXJndW1lbnRUeXBlKG5vZGUsIGNvbnRleHQpIHtcbiAgY29uc3Qga25vd24gPSBrbm93bkV4cHJlc3Npb25UeXBlKG5vZGUsIGNvbnRleHQpXG5cbiAgaWYgKGtub3duKSByZXR1cm4ga25vd25cbiAgaWYgKG5vZGUua2luZCA9PSBcIm51bWJlclwiICYmIE51bWJlci5pc1NhZmVJbnRlZ2VyKE51bWJlcigvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTnVtYmVyfSAqLyAobm9kZSkudmFsdWUpKSkge1xuICAgIHJldHVybiBzY2FsYXJUeXBlKFwiaW50ZWdlclwiKVxuICB9XG4gIGlmIChub2RlLmtpbmQgPT0gXCJib29sZWFuXCIgJiYgdHlwZW9mIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Cb29sZWFufSAqLyAobm9kZSkudmFsdWUgPT0gXCJib29sZWFuXCIpIHtcbiAgICByZXR1cm4gc2NhbGFyVHlwZShcImJvb2xlYW5cIilcbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwic3RyaW5nXCIgJiYgdHlwZW9mIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovIChub2RlKS52YWx1ZSA9PSBcInN0cmluZ1wiICYmXG4gICAgaGFzT25seVVuaWNvZGVTY2FsYXJzKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovIChub2RlKS52YWx1ZSkpIHtcbiAgICByZXR1cm4gc2NhbGFyVHlwZShcInN0cmluZ1wiKVxuICB9XG5cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIFJlc29sdmVzIFBIUCdzIGV4YWN0IHplcm8tYXJndW1lbnQgYWNjZXNzb3IgY2FycmllciBhZ2FpbnN0IGl0cyByZWNlaXZlcidzXG4gKiBnZW5lcmljIHJlY29yZCBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Qcm9wZXJ0eUxvb2t1cH0gbG9va3VwIC0gUGFyc2VyLW93bmVkIG1ldGhvZCBsb29rdXAuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlIHwgdW5kZWZpbmVkfSBJbnN0YW50aWF0ZWQgZmllbGQgdHlwZS5cbiAqL1xuZnVuY3Rpb24ga25vd25HZW5lcmljUmVjb3JkQWNjZXNzb3JUeXBlKGxvb2t1cCwgY29udGV4dCkge1xuICBjb25zdCByZWNlaXZlciA9IGtub3duRXhwcmVzc2lvblR5cGUobG9va3VwLndoYXQsIGNvbnRleHQpXG4gIGNvbnN0IHJlY2VpdmVyUmVjb3JkID0gcmVjZWl2ZXI/LmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIiA/IHJlY2VpdmVyLnZhbHVlVHlwZSA6IHJlY2VpdmVyXG5cbiAgaWYgKHJlY2VpdmVyUmVjb3JkPy5raW5kICE9IFwiUmVjb3JkVHlwZVwiKSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gY29udGV4dC5yZWNvcmRzLmdldChyZWNlaXZlclJlY29yZC5kZWNsYXJhdGlvbklkKVxuICBjb25zdCBtZW1iZXIgPSBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGxvb2t1cC5vZmZzZXQpIDogdW5kZWZpbmVkXG4gIGNvbnN0IGluZGV4ID0gbWVtYmVyICYmIHR5cGVvZiBtZW1iZXIubmFtZSA9PSBcInN0cmluZ1wiXG4gICAgPyBkZWNsYXJhdGlvbj8uZmllbGRzLmZpbmRJbmRleCgoZmllbGQpID0+IGZpZWxkLm5hbWUgPT0gbWVtYmVyLm5hbWUpID8/IC0xXG4gICAgOiAtMVxuXG4gIGlmICghZGVjbGFyYXRpb24gfHwgKGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzPy5sZW5ndGggPz8gMCkgPT0gMCB8fCBpbmRleCA8IDApIHJldHVybiB1bmRlZmluZWRcblxuICByZXR1cm4gaW5zdGFudGlhdGVkUmVjb3JkRmllbGRUeXBlKGRlY2xhcmF0aW9uLCByZWNlaXZlclJlY29yZC5hcmd1bWVudHMsIGluZGV4KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleHBsaWNpdCBQSFAgcmV0dXJuLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJldHVyblN0YXRlbWVudH0gU2VtYW50aWMgcmV0dXJuLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UmV0dXJuKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5raW5kICE9IFwicmV0dXJuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBub2RlLmtpbmQsIGxvY2F0aW9uKVxuXG4gIGNvbnN0IHJldHVybk5vZGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUmV0dXJufSAqLyAobm9kZSlcbiAgY29uc3QgZXhwZWN0ZWRUeXBlID0gY29udGV4dC5yZXR1cm5UeXBlPy5raW5kID09IFwiVHlwZVJlZmVyZW5jZVwiICYmIGNvbnRleHQucmV0dXJuVHlwZS5uYW1lID09IFwidm9pZFwiXG4gICAgPyB1bmRlZmluZWRcbiAgICA6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGUgfCB1bmRlZmluZWR9ICovIChjb250ZXh0LnJldHVyblR5cGUpXG5cbiAgcmV0dXJuIHtcbiAgICAuLi4ocmV0dXJuTm9kZS5leHByID8ge2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKHJldHVybk5vZGUuZXhwciwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZXhwZWN0ZWRUeXBlKX0gOiB7fSksXG4gICAga2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogUmVhZHMgb25lIGV4YWN0IFBIUCBsb2NhbCBgQHZhcmAgY2FycmllciBhbmQgaW1tdXRhYmlsaXR5IG1hcmtlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gQXNzaWdubWVudC1vd25pbmcgc3RhdGVtZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NhbCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXI+fSBbdHlwZVBhcmFtZXRlcnNdIC0gRGVjbGFyYXRpb24tc2NvcGVkIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyB7e2ltbXV0YWJsZTogYm9vbGVhbiwgdHlwZTogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IHwgdW5kZWZpbmVkfSBNZXRhZGF0YSB3aGVuIHByZXNlbnQuXG4gKi9cbmZ1bmN0aW9uIGxvY2FsTWV0YWRhdGEobm9kZSwgbmFtZSwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJzID0gbmV3IE1hcCgpKSB7XG4gIGNvbnN0IGNvbW1lbnRzID0gbm9kZS5sZWFkaW5nQ29tbWVudHMgPz8gW11cbiAgY29uc3QgY29tbWVudCA9IGNvbW1lbnRzLmF0KC0xKVxuXG4gIGlmICghY29tbWVudCB8fCBjb21tZW50LmtpbmQgIT0gXCJjb21tZW50YmxvY2tcIiB8fCAhY29tbWVudC5sb2MgfHwgIW5vZGUubG9jKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgY29uc3QgZ2FwID0gc291cmNlLnNsaWNlKGNvbW1lbnQubG9jLmVuZC5vZmZzZXQsIG5vZGUubG9jLnN0YXJ0Lm9mZnNldClcblxuICBpZiAoIS9eXFxzKiQvdS50ZXN0KGdhcCkgfHwgKGdhcC5tYXRjaCgvXFxuL2d1KT8ubGVuZ3RoID8/IDApID4gMSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IGJsb2NrID0gcGFyc2VDb21tZW50KGNvbW1lbnQudmFsdWUpWzBdXG4gIGNvbnN0IHRhZ3MgPSBibG9jaz8udGFncyA/PyBbXVxuICBjb25zdCB2YXJpYWJsZXMgPSB0YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwidmFyXCIpXG4gIGNvbnN0IGltbXV0YWJsZSA9IHRhZ3MuZmlsdGVyKCh0YWcpID0+IHRhZy50YWcgPT0gXCJzZW1hbnRpZm9sZC1pbW11dGFibGVcIilcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAodmFyaWFibGVzLmxlbmd0aCA9PSAwICYmIGltbXV0YWJsZS5sZW5ndGggPT0gMCkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIGNvbnN0IGV4YWN0VmFyaWFibGUgPSB2YXJpYWJsZXMubGVuZ3RoID09IDEgJiYgdmFyaWFibGVzWzBdLnR5cGUgPT0gXCJcIiAmJiB2YXJpYWJsZXNbMF0uZGVzY3JpcHRpb24gPT0gYCQke25hbWV9YFxuICBjb25zdCBleGFjdEltbXV0YWJsZSA9IGltbXV0YWJsZS5sZW5ndGggPD0gMSAmJiBpbW11dGFibGUuZXZlcnkoKHRhZykgPT4gdGFnLm5hbWUgPT0gXCJcIiAmJiB0YWcudHlwZSA9PSBcIlwiICYmIHRhZy5kZXNjcmlwdGlvbiA9PSBcIlwiKVxuICBjb25zdCBrbm93blRhZ3MgPSB0YWdzLmV2ZXJ5KCh0YWcpID0+IHRhZy50YWcgPT0gXCJ2YXJcIiB8fCB0YWcudGFnID09IFwic2VtYW50aWZvbGQtaW1tdXRhYmxlXCIpXG5cbiAgaWYgKCFleGFjdFZhcmlhYmxlIHx8ICFleGFjdEltbXV0YWJsZSB8fCAha25vd25UYWdzKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFsZm9ybWVkIGxvY2FsIHR5cGUgbWV0YWRhdGFcIiwgbG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4ge1xuICAgIGltbXV0YWJsZTogaW1tdXRhYmxlLmxlbmd0aCA9PSAxLFxuICAgIHR5cGU6IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe1xuICAgICAgbGFuZ3VhZ2U6IFwicGhwXCIsXG4gICAgICBsb2NhdGlvbjogY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHZhcmlhYmxlc1swXSwgXCJuYW1lXCIsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgb3duZXJMb2NhdGlvbjogbG9jYXRpb24sXG4gICAgICByZWNvcmRzOiByZWNvcmROYW1lcyxcbiAgICAgIHNvdXJjZSxcbiAgICAgIHNvdXJjZVR5cGU6IHZhcmlhYmxlc1swXS5uYW1lLFxuICAgICAgc3ViamVjdDogYExvY2FsICcke25hbWV9J2AsXG4gICAgICB0eXBlUGFyYW1ldGVyc1xuICAgIH0pXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgUEhQIGxvY2FsIGRlY2xhcmF0aW9uIG9yIGFzc2lnbm1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuTm9kZX0gbm9kZSAtIFBIUCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Mb2NhbFN0YXRlbWVudCB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50fSBTZW1hbnRpYyBsb2NhbCBvciBwcml2YXRlLWZpZWxkIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydExvY2FsU3RhdGVtZW50KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5raW5kICE9IFwiZXhwcmVzc2lvbnN0YXRlbWVudFwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgbm9kZS5raW5kLCBsb2NhdGlvbilcblxuICBjb25zdCBleHByZXNzaW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkV4cHJlc3Npb25TdGF0ZW1lbnR9ICovIChub2RlKS5leHByZXNzaW9uXG5cbiAgaWYgKGV4cHJlc3Npb24ua2luZCAhPSBcImFzc2lnblwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgZXhwcmVzc2lvbi5raW5kLCBub2RlTG9jYXRpb24oZXhwcmVzc2lvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG5cbiAgY29uc3QgYXNzaWdubWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Bc3NpZ259ICovIChleHByZXNzaW9uKVxuXG4gIGlmIChhc3NpZ25tZW50Lm9wZXJhdG9yICE9IFwiPVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYGFzc2lnbm1lbnQgJHthc3NpZ25tZW50Lm9wZXJhdG9yfWAsIGxvY2F0aW9uKVxuICBpZiAoYXNzaWdubWVudC5sZWZ0LmtpbmQgPT0gXCJwcm9wZXJ0eWxvb2t1cFwiICYmIGNvbnRleHQuY3VycmVudENsYXNzKSB7XG4gICAgY29uc3QgbG9va3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAoYXNzaWdubWVudC5sZWZ0KVxuICAgIGNvbnN0IHJlY2VpdmVyID0gbG9va3VwLndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBtZW1iZXIgPSBsb29rdXAub2Zmc2V0LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKGxvb2t1cC5vZmZzZXQpIDogdW5kZWZpbmVkXG4gICAgY29uc3QgZmllbGQgPSByZWNlaXZlcj8ubmFtZSA9PSBcInRoaXNcIiAmJiBtZW1iZXIgJiYgdHlwZW9mIG1lbWJlci5uYW1lID09IFwic3RyaW5nXCJcbiAgICAgID8gY29udGV4dC5jdXJyZW50Q2xhc3MuZmllbGRzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT0gbWVtYmVyLm5hbWUpXG4gICAgICA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKCFmaWVsZCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicHJpdmF0ZSBmaWVsZCB3cml0ZSBvdXRzaWRlIHRoZSBkZWNsYXJpbmcgcmVjZWl2ZXJcIiwgbm9kZUxvY2F0aW9uKGFzc2lnbm1lbnQubGVmdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKGFzc2lnbm1lbnQucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGZpZWxkLnR5cGUpLFxuICAgICAgZmllbGQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZmllbGQuaWQpLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQcml2YXRlRmllbGRXcml0ZVN0YXRlbWVudFwiKSwgbG9jYXRpb24sXG4gICAgICByZWNlaXZlcjogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNlaXZlckV4cHJlc3Npb259ICovIChcbiAgICAgICAgY29udmVydEV4cHJlc3Npb24obG9va3VwLndoYXQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpKX0sXG4gICAge21lbWJlcjogbm9kZUxvY2F0aW9uKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAobWVtYmVyKSwgZmlsZW5hbWUsIHNvdXJjZSksIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiPVwiLCBhc3NpZ25tZW50LmxlZnQubG9jPy5lbmQub2Zmc2V0ID8/IDAsXG4gICAgICBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfVxuICBpZiAoYXNzaWdubWVudC5sZWZ0LmtpbmQgIT0gXCJ2YXJpYWJsZVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgYXNzaWdubWVudC5sZWZ0LmtpbmQsIG5vZGVMb2NhdGlvbihhc3NpZ25tZW50LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBpZiAoYXNzaWdubWVudC5yaWdodC5raW5kID09IFwidGhyb3dcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInRocm93IGV4cHJlc3Npb24gaW4gYSB2YWx1ZSBjb250ZXh0XCIsIG5vZGVMb2NhdGlvbihhc3NpZ25tZW50LnJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGNvbnN0IHZhcmlhYmxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAoYXNzaWdubWVudC5sZWZ0KVxuICBjb25zdCB0YXJnZXRMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbih2YXJpYWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIiB8fCB2YXJpYWJsZS5jdXJseSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyB2YXJpYWJsZVwiLCB0YXJnZXRMb2NhdGlvbilcblxuICBjb25zdCBtZXRhZGF0YSA9IGxvY2FsTWV0YWRhdGEobm9kZSwgdmFyaWFibGUubmFtZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dC5yZWNvcmROYW1lcywgY29udGV4dC50eXBlUGFyYW1ldGVycylcblxuICBpZiAobWV0YWRhdGEpIHtcbiAgICBsZXQgZGVjbGFyZWRUeXBlID0gbWV0YWRhdGEudHlwZVxuICAgIGxldCBvcmRlcmVkID0gZmFsc2VcblxuICAgIGlmIChkZWNsYXJlZFR5cGUua2luZCA9PSBcIk1hcFR5cGVcIiAmJiBjb250ZXh0Lm9yZGVyZWRNYXBEZWNsYXJhdGlvbnM/Lmhhcyhhc3NpZ25tZW50KSAmJiBhc3NpZ25tZW50LnJpZ2h0LmtpbmQgPT0gXCJhcnJheVwiKSB7XG4gICAgICBkZWNsYXJlZFR5cGUgPSBvcmRlcmVkTWFwVHlwZUZyb21NYXAoZGVjbGFyZWRUeXBlLCBsb2NhdGlvbilcbiAgICAgIG9yZGVyZWQgPSB0cnVlXG4gICAgfVxuICAgIGNvbnN0IGluaXRpYWxpemVyID0gY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgZGVjbGFyZWRUeXBlKVxuXG4gICAgY29udGV4dC5iaW5kaW5ncy5zZXQodmFyaWFibGUubmFtZSwgZGVjbGFyZWRUeXBlKVxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGluaXRpYWxpemVyLFxuICAgICAga2luZDogXCJMb2NhbERlY2xhcmF0aW9uXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG11dGFibGU6IG9yZGVyZWQgPyBmYWxzZSA6ICFtZXRhZGF0YS5pbW11dGFibGUsXG4gICAgICBuYW1lOiB2YXJpYWJsZS5uYW1lLFxuICAgICAgdHlwZTogZGVjbGFyZWRUeXBlXG4gICAgfSwge1xuICAgICAgbmFtZTogdGFyZ2V0TG9jYXRpb24sXG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIGNvbnN0IGluZmVycmVkVHlwZSA9IGtub3duRXhwcmVzc2lvblR5cGUoYXNzaWdubWVudC5yaWdodCwgY29udGV4dClcblxuICBpZiAoaW5mZXJyZWRUeXBlPy5raW5kID09IFwiUmVjb3JkVHlwZVwiIHx8IGluZmVycmVkVHlwZT8ua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIiB8fFxuICAgIGluZmVycmVkVHlwZT8ua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpIHtcbiAgICBjb25zdCBpbml0aWFsaXplciA9IGNvbnZlcnRFeHByZXNzaW9uKGFzc2lnbm1lbnQucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGluZmVycmVkVHlwZSlcblxuICAgIGNvbnRleHQuYmluZGluZ3Muc2V0KHZhcmlhYmxlLm5hbWUsIGluZmVycmVkVHlwZSlcbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBpbml0aWFsaXplcixcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxvY2FsRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG11dGFibGU6IGZhbHNlLFxuICAgICAgbmFtZTogdmFyaWFibGUubmFtZSxcbiAgICAgIHR5cGU6IGluZmVycmVkVHlwZVxuICAgIH0sIHtcbiAgICAgIG5hbWU6IHRhcmdldExvY2F0aW9uLFxuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oXCI9XCIsIGFzc2lnbm1lbnQubGVmdC5sb2M/LmVuZC5vZmZzZXQgPz8gMCwgYXNzaWdubWVudC5yaWdodC5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pXG4gIH1cblxuICBjb25zdCBiaW5kaW5nVHlwZSA9IGNvbnRleHQuYmluZGluZ3MuZ2V0KHZhcmlhYmxlLm5hbWUpXG5cbiAgaWYgKCFiaW5kaW5nVHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBMb2NhbCAnJHt2YXJpYWJsZS5uYW1lfSdgLCBsb2NhdGlvbilcblxuICBjb25zdCB0YXJnZXQgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHRhcmdldExvY2F0aW9uLCBuYW1lOiB2YXJpYWJsZS5uYW1lfSwge1xuICAgIG5hbWU6IHRhcmdldExvY2F0aW9uXG4gIH0pXG4gIGNvbnN0IHZhbHVlID0gY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCxcbiAgICBiaW5kaW5nVHlwZS5raW5kID09IFwiRXJyb3JUeXBlXCIgPyB1bmRlZmluZWQgOiBiaW5kaW5nVHlwZSlcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgZXhwcmVzc2lvbjogdmFsdWUsXG4gICAga2luZDogXCJBc3NpZ25tZW50U3RhdGVtZW50XCIsXG4gICAgbG9jYXRpb24sXG4gICAgdGFyZ2V0XG4gIH0sIHtcbiAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmxvYz8uZW5kLm9mZnNldCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0pXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGV4aGF1c3RpdmUgUEhQIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU2VtYW50aWMgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0U3RhdGVtZW50KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgaWYgKG5vZGUua2luZCA9PSBcInJldHVyblwiKSByZXR1cm4gY29udmVydFJldHVybihub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICBpZiAobm9kZS5raW5kID09IFwiaWZcIikgcmV0dXJuIGNvbnZlcnRJZigvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSWZ9ICovIChub2RlKSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgaWYgKG5vZGUua2luZCA9PSBcInRocm93XCIpIHJldHVybiBjb252ZXJ0UGhwUmFpc2Uobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgaWYgKG5vZGUua2luZCA9PSBcInRyeVwiKSByZXR1cm4gY29udmVydFBocFRyeShub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICBpZiAobm9kZS5raW5kID09IFwid2hpbGVcIikgcmV0dXJuIGNvbnZlcnRXaGlsZSgvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuV2hpbGV9ICovIChub2RlKSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgaWYgKG5vZGUua2luZCA9PSBcImZvcmVhY2hcIikgcmV0dXJuIGNvbnZlcnRGb3JFYWNoKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Gb3JlYWNofSAqLyAobm9kZSksIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIGlmIChub2RlLmtpbmQgPT0gXCJicmVha1wiIHx8IG5vZGUua2luZCA9PSBcImNvbnRpbnVlXCIpIHtcbiAgICBjb25zdCBjb250cm9sID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJyZWFrIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5Db250aW51ZX0gKi8gKG5vZGUpXG5cbiAgICBpZiAoY29udHJvbC5sZXZlbCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGAke25vZGUua2luZH0gbGV2ZWxgLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgY29uc3QgbG9jYXRpb24gPSB0b2tlbkxvY2F0aW9uKG5vZGUua2luZCwgbm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBub2RlLmxvYz8uZW5kLm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogLyoqIEB0eXBlIHtcIkJyZWFrU3RhdGVtZW50XCIgfCBcIkNvbnRpbnVlU3RhdGVtZW50XCJ9ICovIChub2RlLmtpbmQgPT0gXCJicmVha1wiID8gXCJCcmVha1N0YXRlbWVudFwiIDogXCJDb250aW51ZVN0YXRlbWVudFwiKSxcbiAgICAgIGxvY2F0aW9uXG4gICAgfSwge2tleXdvcmQ6IGxvY2F0aW9ufSlcbiAgfVxuICBpZiAobm9kZS5raW5kID09IFwiZWNob1wiKSByZXR1cm4gY29udmVydFByaW50KC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FY2hvfSAqLyAobm9kZSksIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIGlmIChub2RlLmtpbmQgPT0gXCJleHByZXNzaW9uc3RhdGVtZW50XCIpIHtcbiAgICBjb25zdCBleHByZXNzaW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkV4cHJlc3Npb25TdGF0ZW1lbnR9ICovIChub2RlKS5leHByZXNzaW9uXG5cbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiY2FsbFwiKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleHByZXNzaW9uOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhbGxFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTWV0aG9kQ2FsbEV4cHJlc3Npb259ICovIChcbiAgICAgICAgICBjb252ZXJ0RXhwcmVzc2lvbihleHByZXNzaW9uLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgICAgICApLFxuICAgICAgICBraW5kOiBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIixcbiAgICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb252ZXJ0TG9jYWxTdGF0ZW1lbnQobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgfVxuXG4gIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBub2RlLmtpbmQsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBleGFjdCBgdGhyb3cgbmV3IERlY2xhcmVkRXJyb3IobWVzc2FnZSlgLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBQSFAgdGhyb3cgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge1BocENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgbGV4aWNhbCBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJhaXNlU3RhdGVtZW50fSBTZW1hbnRpYyByYWlzZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFBocFJhaXNlKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY29uc3RydWN0aW9uID0gUmVmbGVjdC5nZXQobm9kZSwgXCJ3aGF0XCIpXG5cbiAgaWYgKCFjb25zdHJ1Y3Rpb24gfHwgY29uc3RydWN0aW9uLmtpbmQgIT0gXCJuZXdcIiB8fCBjb25zdHJ1Y3Rpb24ud2hhdD8ua2luZCAhPSBcIm5hbWVcIiB8fFxuICAgIGNvbnN0cnVjdGlvbi53aGF0LnJlc29sdXRpb24gIT0gXCJ1cW5cIiB8fCAhY29udGV4dC5lcnJvck5hbWVzLmhhcyhjb25zdHJ1Y3Rpb24ud2hhdC5uYW1lKSB8fFxuICAgICFBcnJheS5pc0FycmF5KGNvbnN0cnVjdGlvbi5hcmd1bWVudHMpIHx8IGNvbnN0cnVjdGlvbi5hcmd1bWVudHMubGVuZ3RoICE9IDEgfHxcbiAgICBjb25zdHJ1Y3Rpb24uYXJndW1lbnRzWzBdLmtpbmQgPT0gXCJuYW1lZGFyZ3VtZW50XCIgfHwgY29uc3RydWN0aW9uLmFyZ3VtZW50c1swXS5raW5kID09IFwidmFyaWFkaWNcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInRocm93IG90aGVyIHRoYW4gZXhhY3QgZGVjbGFyZWQgZXJyb3IgY29uc3RydWN0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSAqLyAoY29udGV4dC5lcnJvck5hbWVzLmdldChjb25zdHJ1Y3Rpb24ud2hhdC5uYW1lKSlcbiAgY29uc3QgdHlwZUxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGNvbnN0cnVjdGlvbi53aGF0LCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBlcnJvcjogd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBlcnJvcjogd2l0aFBhcnNlclJhbmdlcyh7ZGVjbGFyYXRpb25JZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVycm9yVHlwZVwiKX0sIHt0eXBlOiB0eXBlTG9jYXRpb259KSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkVycm9yQ29uc3RydWN0aW9uXCIpLFxuICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihjb25zdHJ1Y3Rpb24sIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbWVzc2FnZTogY29udmVydEV4cHJlc3Npb24oY29uc3RydWN0aW9uLmFyZ3VtZW50c1swXSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICB9LCB7dHlwZTogdHlwZUxvY2F0aW9ufSksXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmFpc2VTdGF0ZW1lbnRcIiksXG4gICAgbG9jYXRpb25cbiAgfSwge2tleXdvcmQ6IHRva2VuTG9jYXRpb24oXCJ0aHJvd1wiLCBub2RlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGNvbnN0cnVjdGlvbi5sb2M/LnN0YXJ0Lm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGV4YWN0IHR5cGVkIGNhdGNoIHdpdGggbm8gZmluYWxseS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBub2RlIC0gUEhQIHRyeSBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7UGhwQ29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHJ5U3RhdGVtZW50fSBTZW1hbnRpYyBleGFjdCBoYW5kbGVyLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGhwVHJ5KG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY2F0Y2hlcyA9IFJlZmxlY3QuZ2V0KG5vZGUsIFwiY2F0Y2hlc1wiKVxuICBjb25zdCBib2R5ID0gUmVmbGVjdC5nZXQobm9kZSwgXCJib2R5XCIpXG5cbiAgaWYgKFJlZmxlY3QuZ2V0KG5vZGUsIFwiYWx3YXlzXCIpIHx8ICFBcnJheS5pc0FycmF5KGNhdGNoZXMpIHx8IGNhdGNoZXMubGVuZ3RoICE9IDEgfHwgYm9keT8ua2luZCAhPSBcImJsb2NrXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJ0cnkgd2l0aG91dCBvbmUgdHlwZWQgY2F0Y2ggYW5kIG5vIGZpbmFsbHlcIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgaGFuZGxlciA9IGNhdGNoZXNbMF1cbiAgY29uc3QgY2F1Z2h0ID0gaGFuZGxlci53aGF0Py5bMF1cbiAgY29uc3QgYmluZGluZyA9IGhhbmRsZXIudmFyaWFibGVcblxuICBpZiAoaGFuZGxlci53aGF0Py5sZW5ndGggIT0gMSB8fCBjYXVnaHQ/LmtpbmQgIT0gXCJuYW1lXCIgfHwgY2F1Z2h0LnJlc29sdXRpb24gIT0gXCJ1cW5cIiB8fFxuICAgICFjb250ZXh0LmVycm9yTmFtZXMuaGFzKGNhdWdodC5uYW1lKSB8fCBiaW5kaW5nPy5raW5kICE9IFwidmFyaWFibGVcIiB8fCB0eXBlb2YgYmluZGluZy5uYW1lICE9IFwic3RyaW5nXCIgfHxcbiAgICBiaW5kaW5nLmN1cmx5IHx8IGhhbmRsZXIuYm9keT8ua2luZCAhPSBcImJsb2NrXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJicm9hZCwgbXVsdGlwbGUsIG9yIG1hbGZvcm1lZCBjYXRjaFwiLCBub2RlTG9jYXRpb24oaGFuZGxlciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZGVjbGFyYXRpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb259ICovIChjb250ZXh0LmVycm9yTmFtZXMuZ2V0KGNhdWdodC5uYW1lKSlcbiAgY29uc3QgY2F1Z2h0TG9jYXRpb24gPSBub2RlTG9jYXRpb24oY2F1Z2h0LCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBjYXRjaFR5cGUgPSB3aXRoUGFyc2VyUmFuZ2VzKHtkZWNsYXJhdGlvbklkOiAvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JUeXBlXCIpfSwge1xuICAgIHR5cGU6IGNhdWdodExvY2F0aW9uXG4gIH0pXG4gIGNvbnN0IGJvZHlDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuICBjb25zdCBjYXRjaENvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG5cbiAgY2F0Y2hDb250ZXh0LmJpbmRpbmdzLnNldChiaW5kaW5nLm5hbWUsIGNhdGNoVHlwZSlcbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGJvZHk6IGNvbnZlcnRCbG9jayhib2R5LCBmaWxlbmFtZSwgc291cmNlLCBib2R5Q29udGV4dCksXG4gICAgY2F0Y2hCaW5kaW5nOiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkNhdGNoQmluZGluZ1wiKSxcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24oYmluZGluZywgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZTogYmluZGluZy5uYW1lLFxuICAgICAgdHlwZTogY2F0Y2hUeXBlXG4gICAgfSwge25hbWU6IG5vZGVMb2NhdGlvbihiaW5kaW5nLCBmaWxlbmFtZSwgc291cmNlKX0pLFxuICAgIGNhdGNoQm9keTogY29udmVydEJsb2NrKGhhbmRsZXIuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSwgY2F0Y2hDb250ZXh0KSxcbiAgICBjYXRjaFR5cGUsXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHJ5U3RhdGVtZW50XCIpLFxuICAgIGxvY2F0aW9uXG4gIH0sIHtjYXRjaDogbm9kZUxvY2F0aW9uKGhhbmRsZXIsIGZpbGVuYW1lLCBzb3VyY2UpLCB0cnk6IHRva2VuTG9jYXRpb24oXCJ0cnlcIiwgbm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBib2R5LmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBleGFjdCBibG9jay1mb3JtIFBIUCBgZm9yZWFjaCAoJGxpc3QgYXMgJHZhbHVlKWAuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRm9yZWFjaH0gbm9kZSAtIFBIUCBmb3JlYWNoIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoU3RhdGVtZW50IHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRm9yRWFjaE1hcFN0YXRlbWVudH0gU2VtYW50aWMgbG9vcC5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZvckVhY2gobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnNob3J0Rm9ybSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiYWx0ZXJuYXRpdmUgZm9yZWFjaCBzeW50YXhcIiwgbG9jYXRpb24pXG4gIGlmIChub2RlLnZhbHVlLmtpbmQgIT0gXCJ2YXJpYWJsZVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmb3JlYWNoIGRlc3RydWN0dXJpbmdcIiwgbm9kZUxvY2F0aW9uKG5vZGUudmFsdWUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCB2YXJpYWJsZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5WYXJpYWJsZX0gKi8gKG5vZGUudmFsdWUpXG5cbiAgaWYgKFJlZmxlY3QuZ2V0KHZhcmlhYmxlLCBcImJ5cmVmXCIpID09PSB0cnVlKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJieS1yZWZlcmVuY2UgZm9yZWFjaFwiLCBub2RlTG9jYXRpb24odmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBpZiAodHlwZW9mIHZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIiB8fCB2YXJpYWJsZS5jdXJseSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZHluYW1pYyBmb3JlYWNoIGJpbmRpbmdcIiwgbm9kZUxvY2F0aW9uKHZhcmlhYmxlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgaWYgKCFub2RlLmJvZHkgfHwgbm9kZS5ib2R5LmtpbmQgIT0gXCJibG9ja1wiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZm9yZWFjaCB3aXRob3V0IGJsb2NrIGJvZHlcIiwgbm9kZS5ib2R5ID8gbm9kZUxvY2F0aW9uKG5vZGUuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSkgOiBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBib2R5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5ib2R5KVxuICBjb25zdCBjb2xsZWN0aW9uVHlwZSA9IGl0ZXJhdGlvbk9wZXJhbmRUeXBlKGtub3duRXhwcmVzc2lvblR5cGUobm9kZS5zb3VyY2UsIGNvbnRleHQpKVxuXG4gIGlmIChub2RlLmtleSkge1xuICAgIGlmIChub2RlLmtleS5raW5kICE9IFwidmFyaWFibGVcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZm9yZWFjaCBrZXkgYmluZGluZyBzaGFwZVwiLCBub2RlTG9jYXRpb24obm9kZS5rZXksIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGNvbnN0IGtleVZhcmlhYmxlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAobm9kZS5rZXkpXG5cbiAgICBpZiAoUmVmbGVjdC5nZXQoa2V5VmFyaWFibGUsIFwiYnlyZWZcIikgPT09IHRydWUgfHwgdHlwZW9mIGtleVZhcmlhYmxlLm5hbWUgIT0gXCJzdHJpbmdcIiB8fCBrZXlWYXJpYWJsZS5jdXJseSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaW52YWxpZCBmb3JlYWNoIGtleSBiaW5kaW5nXCIsIG5vZGVMb2NhdGlvbihrZXlWYXJpYWJsZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGlmIChjb2xsZWN0aW9uVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwidW5vcmRlcmVkIG1hcCBpdGVyYXRpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgaWYgKCFjb2xsZWN0aW9uVHlwZSB8fCBjb2xsZWN0aW9uVHlwZS5raW5kICE9IFwiT3JkZXJlZE1hcFR5cGVcIikge1xuICAgICAgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIFwiT3JkZXJlZCBtYXAgaXRlcmF0aW9uIGNvbGxlY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3Qga2V5TG9jYXRpb24gPSBub2RlTG9jYXRpb24oa2V5VmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgdmFsdWVMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbih2YXJpYWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBrZXlUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoY29sbGVjdGlvblR5cGUua2V5VHlwZSwga2V5TG9jYXRpb24pXG4gICAgY29uc3QgdmFsdWVUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoY29sbGVjdGlvblR5cGUudmFsdWVUeXBlLCB2YWx1ZUxvY2F0aW9uKVxuICAgIGNvbnN0IGtleUJpbmRpbmcgPSB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlZhbHVlQmluZGluZ1wiKSwgbG9jYXRpb246IGtleUxvY2F0aW9uLCBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZToga2V5VmFyaWFibGUubmFtZSwgdHlwZToga2V5VHlwZVxuICAgIH0sIHtuYW1lOiBrZXlMb2NhdGlvbn0pXG4gICAgY29uc3QgdmFsdWVCaW5kaW5nID0gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJWYWx1ZUJpbmRpbmdcIiksIGxvY2F0aW9uOiB2YWx1ZUxvY2F0aW9uLCBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZTogdmFyaWFibGUubmFtZSwgdHlwZTogdmFsdWVUeXBlXG4gICAgfSwge25hbWU6IHZhbHVlTG9jYXRpb259KVxuICAgIGNvbnN0IGJvZHlDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuXG4gICAgYm9keUNvbnRleHQuYmluZGluZ3Muc2V0KGtleVZhcmlhYmxlLm5hbWUsIGtleVR5cGUpXG4gICAgYm9keUNvbnRleHQuYmluZGluZ3Muc2V0KHZhcmlhYmxlLm5hbWUsIHZhbHVlVHlwZSlcbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBib2R5OiBjb252ZXJ0QmxvY2soYm9keSwgZmlsZW5hbWUsIHNvdXJjZSwgYm9keUNvbnRleHQpLFxuICAgICAga2V5QmluZGluZyxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkZvckVhY2hNYXBTdGF0ZW1lbnRcIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG1hcDogY29udmVydEV4cHJlc3Npb24obm9kZS5zb3VyY2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgdmFsdWVCaW5kaW5nXG4gICAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiZm9yZWFjaFwiLCBub2RlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIG5vZGUuc291cmNlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsXG4gICAgICBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH1cblxuICBpZiAoY29sbGVjdGlvblR5cGU/LmtpbmQgPT0gXCJNYXBUeXBlXCIgfHwgY29sbGVjdGlvblR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFwIGl0ZXJhdGlvbiB3aXRob3V0IGtleS92YWx1ZSBwYWlyIGJpbmRpbmdcIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBpZiAoIWNvbGxlY3Rpb25UeXBlIHx8IGNvbGxlY3Rpb25UeXBlLmtpbmQgIT0gXCJMaXN0VHlwZVwiKSB7XG4gICAgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIFwiSXRlcmF0aW9uIGNvbGxlY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCBiaW5kaW5nTG9jYXRpb24gPSBub2RlTG9jYXRpb24odmFyaWFibGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGluZmVycmVkVHlwZSA9IGNvbGxlY3Rpb25UeXBlLmVsZW1lbnRUeXBlXG4gIGNvbnN0IGJpbmRpbmdUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoaW5mZXJyZWRUeXBlLCBiaW5kaW5nTG9jYXRpb24pXG4gIGNvbnN0IHZhbHVlQmluZGluZyA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlZhbHVlQmluZGluZ1wiKSxcbiAgICBsb2NhdGlvbjogYmluZGluZ0xvY2F0aW9uLFxuICAgIG11dGFibGU6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSksXG4gICAgbmFtZTogdmFyaWFibGUubmFtZSxcbiAgICB0eXBlOiBiaW5kaW5nVHlwZVxuICB9LCB7bmFtZTogYmluZGluZ0xvY2F0aW9ufSlcbiAgY29uc3QgYm9keUNvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG5cbiAgYm9keUNvbnRleHQuYmluZGluZ3Muc2V0KHZhcmlhYmxlLm5hbWUsIGJpbmRpbmdUeXBlKVxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keTogY29udmVydEJsb2NrKGJvZHksIGZpbGVuYW1lLCBzb3VyY2UsIGJvZHlDb250ZXh0KSxcbiAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJGb3JFYWNoU3RhdGVtZW50XCIpLFxuICAgIGxpc3Q6IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICBsb2NhdGlvbixcbiAgICB2YWx1ZUJpbmRpbmdcbiAgfSwge29wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKFwiZm9yZWFjaFwiLCBub2RlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIG5vZGUuc291cmNlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhbiBvcmRlcmVkIFBIUCBibG9jayB3aXRoIGl0cyBvd24gYWRhcHRhdGlvbiBzY29wZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CbG9ja30gbm9kZSAtIFBIUCBwYXJzZXIgYmxvY2suXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gU2VtYW50aWMgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSB7XG4gIHJldHVybiB7XG4gICAga2luZDogXCJCbG9ja1wiLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgc3RhdGVtZW50czogbm9kZS5jaGlsZHJlbi5tYXAoKHN0YXRlbWVudCkgPT4gY29udmVydFN0YXRlbWVudChzdGF0ZW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpKVxuICB9XG59XG5cbi8qKlxuICogUmVxdWlyZXMgYW4gZXhhY3QgUEhQIHNjYWxhciBkZWNsYXJhdGlvbiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGUgfCBudWxsfSBzb3VyY2VUeXBlIC0gUEhQIHR5cGUgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gU291cmNlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IFtyZWNvcmROYW1lc10gLSBOb21pbmFsIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gU2VtYW50aWMgdHlwZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFR5cGUoc291cmNlVHlwZSwgc3ViamVjdCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghc291cmNlVHlwZSkgcmV0dXJuIHJlcXVpcmVTb3VyY2VTY2FsYXJUeXBlKFwicGhwXCIsIHVuZGVmaW5lZCwgc3ViamVjdCwgbG9jYXRpb24pXG4gIGlmIChzb3VyY2VUeXBlLmtpbmQgIT0gXCJ0eXBlcmVmZXJlbmNlXCIgJiYgc291cmNlVHlwZS5raW5kICE9IFwibmFtZVwiICYmIHNvdXJjZVR5cGUua2luZCAhPSBcImlkZW50aWZpZXJcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIsIG5vZGVMb2NhdGlvbihzb3VyY2VUeXBlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGNvbnN0IHR5cGVOYW1lID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlR5cGVSZWZlcmVuY2UgfCBpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWUgfCBpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChzb3VyY2VUeXBlKS5uYW1lXG5cbiAgY29uc3QgdHlwZUxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gcmVjb3JkTmFtZXMuZ2V0KHR5cGVOYW1lKVxuXG4gIGlmIChkZWNsYXJhdGlvbj8uaWQpIHJldHVybiBkZWNsYXJhdGlvbi5raW5kID09IFwiQ2xhc3NEZWNsYXJhdGlvblwiXG4gICAgPyByZWZlcmVuY2VUeXBlKGRlY2xhcmF0aW9uLmlkLCB0eXBlTG9jYXRpb24pXG4gICAgOiBkZWNsYXJhdGlvbi5raW5kID09IFwiRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvblwiXG4gICAgICA/IG93bmVkUmVzb3VyY2VUeXBlKGRlY2xhcmF0aW9uLmlkLCB0eXBlTG9jYXRpb24pXG4gICAgICA6IHJlY29yZFR5cGUoZGVjbGFyYXRpb24uaWQsIHR5cGVMb2NhdGlvbilcblxuICByZXR1cm4gcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUoXCJwaHBcIiwgdHlwZU5hbWUsIHN1YmplY3QsIGxvY2F0aW9uLCB0eXBlTG9jYXRpb24pXG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGV4YWN0IFBIUERvYyBjb250YWluZXIgc2lnbmF0dXJlIGF0dGFjaGVkIHRvIG9uZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIEZ1bmN0aW9uIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3duZXJJZF0gLSBTdGFibGUgZGVjbGFyYXRpb24gaWRlbnRpdHkuXG4gKiBAcmV0dXJucyB7e3BhcmFtZXRlcnM6IE1hcDxzdHJpbmcsIHtsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNvdXJjZVR5cGU6IHN0cmluZ30+LCByZXR1cm5UeXBlOiB7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBzb3VyY2VUeXBlOiBzdHJpbmd9IHwgdW5kZWZpbmVkLCB0eXBlUGFyYW1ldGVycz86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXJbXX19IERvY3VtZW50ZWQgdHlwZXMuXG4gKi9cbmZ1bmN0aW9uIGZ1bmN0aW9uRG9jdW1lbnRlZFR5cGVzKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIG93bmVySWQpIHtcbiAgY29uc3QgY29tbWVudCA9IG5vZGUubGVhZGluZ0NvbW1lbnRzPy5hdCgtMSlcblxuICBpZiAoIWNvbW1lbnQgfHwgY29tbWVudC5raW5kICE9IFwiY29tbWVudGJsb2NrXCIgfHwgIWNvbW1lbnQubG9jIHx8ICFub2RlLmxvYyB8fFxuICAgICEvXlxccyokL3UudGVzdChzb3VyY2Uuc2xpY2UoY29tbWVudC5sb2MuZW5kLm9mZnNldCwgbm9kZS5sb2Muc3RhcnQub2Zmc2V0KSkpIHJldHVybiB7cGFyYW1ldGVyczogbmV3IE1hcCgpLCByZXR1cm5UeXBlOiB1bmRlZmluZWR9XG4gIGNvbnN0IGJsb2NrID0gcGFyc2VDb21tZW50KGNvbW1lbnQudmFsdWUpWzBdXG4gIGNvbnN0IHRhZ3MgPSBibG9jaz8udGFncyA/PyBbXVxuICBjb25zdCBwYXJhbWV0ZXJUYWdzID0gdGFncy5maWx0ZXIoKHRhZykgPT4gdGFnLnRhZyA9PSBcInBhcmFtXCIpXG4gIGNvbnN0IHJldHVyblRhZ3MgPSB0YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwicmV0dXJuXCIgfHwgdGFnLnRhZyA9PSBcInJldHVybnNcIilcbiAgY29uc3QgdGVtcGxhdGVUYWdzID0gdGFncy5maWx0ZXIoKHRhZykgPT4gdGFnLnRhZyA9PSBcInRlbXBsYXRlXCIpXG4gIGNvbnN0IG1hbGZvcm1lZFRlbXBsYXRlID0gdGFncy5maW5kKCh0YWcpID0+IHRhZy50YWcuc3RhcnRzV2l0aChcInRlbXBsYXRlXCIpICYmIHRhZy50YWcgIT0gXCJ0ZW1wbGF0ZVwiKVxuICBjb25zdCBtYWxmb3JtZWQgPSB0YWdzLnNvbWUoKHRhZykgPT4gIVtcInBhcmFtXCIsIFwicmV0dXJuXCIsIFwicmV0dXJuc1wiLCBcInRlbXBsYXRlXCJdLmluY2x1ZGVzKHRhZy50YWcpKSB8fCByZXR1cm5UYWdzLmxlbmd0aCA+IDEgfHxcbiAgICBwYXJhbWV0ZXJUYWdzLnNvbWUoKHRhZykgPT4gdGFnLnR5cGUgIT0gXCJcIiB8fCAhL15cXCRbQS1aYS16X11bQS1aYS16MC05X10qJC91LnRlc3QodGFnLmRlc2NyaXB0aW9uKSkgfHxcbiAgICByZXR1cm5UYWdzLnNvbWUoKHRhZykgPT4gdGFnLnR5cGUgIT0gXCJcIiB8fCB0YWcuZGVzY3JpcHRpb24gIT0gXCJcIikgfHwgbWFsZm9ybWVkVGVtcGxhdGUgfHxcbiAgICB0ZW1wbGF0ZVRhZ3Muc29tZSgodGFnKSA9PiAhL15bQS1aYS16X11bQS1aYS16MC05X10qJC91LnRlc3QodGFnLm5hbWUpIHx8IHRhZy50eXBlICE9IFwiXCIgfHwgdGFnLmRlc2NyaXB0aW9uICE9IFwiXCIpIHx8XG4gICAgdGVtcGxhdGVUYWdzLmxlbmd0aCA+IDAgJiYgIW93bmVySWRcblxuICBpZiAobWFsZm9ybWVkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJtYWxmb3JtZWQgZnVuY3Rpb24gdHlwZSBhbm5vdGF0aW9uXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgcGFyYW1ldGVycyA9IG5ldyBNYXAocGFyYW1ldGVyVGFncy5tYXAoKHRhZykgPT4gW3RhZy5kZXNjcmlwdGlvbi5zbGljZSgxKSwge1xuICAgIGxvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgdGFnLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgc291cmNlVHlwZTogdGFnLm5hbWVcbiAgfV0pKVxuXG4gIGlmIChwYXJhbWV0ZXJzLnNpemUgIT0gcGFyYW1ldGVyVGFncy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkdXBsaWNhdGUgcGFyYW1ldGVyIGFubm90YXRpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IHJldHVyblRhZyA9IHJldHVyblRhZ3NbMF1cbiAgY29uc3QgdHlwZVBhcmFtZXRlcnMgPSB0ZW1wbGF0ZVRhZ3MubWFwKCh0YWcsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgbG9jYXRpb24gPSBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgdGFnLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtpZDogYCR7b3duZXJJZH06dHlwZToke2luZGV4fWAsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlR5cGVQYXJhbWV0ZXJcIiksIGxvY2F0aW9uLCBuYW1lOiB0YWcubmFtZX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gIH0pXG5cbiAgcmV0dXJuIHtcbiAgICBwYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGU6IHJldHVyblRhZyA/IHtcbiAgICAgIGxvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgcmV0dXJuVGFnLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBzb3VyY2VUeXBlOiByZXR1cm5UYWcubmFtZVxuICAgIH0gOiB1bmRlZmluZWQsXG4gICAgLi4uKHR5cGVQYXJhbWV0ZXJzLmxlbmd0aCA+IDAgPyB7dHlwZVBhcmFtZXRlcnN9IDoge30pXG4gIH1cbn1cblxuLyoqXG4gKiBSZWFkcyBhbiBvcHRpb25hbCBleGFjdCBjbGFzcy1sZXZlbCBQSFBEb2MgdGVtcGxhdGUgbGlzdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5DbGFzc30gbm9kZSAtIENsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG93bmVySWQgLSBTdGFibGUgcmVjb3JkIGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUGFyYW1ldGVyW10gfCB1bmRlZmluZWR9IE9yZGVyZWQgcGFyYW1ldGVycy5cbiAqL1xuZnVuY3Rpb24gY2xhc3NEb2N1bWVudGVkVHlwZVBhcmFtZXRlcnMobm9kZSwgb3duZXJJZCwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBkb2N1bWVudGVkID0gZnVuY3Rpb25Eb2N1bWVudGVkVHlwZXMoXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkZ1bmN0aW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAobm9kZSkpLCBmaWxlbmFtZSwgc291cmNlLCBvd25lcklkKVxuXG4gIGlmIChkb2N1bWVudGVkLnBhcmFtZXRlcnMuc2l6ZSB8fCBkb2N1bWVudGVkLnJldHVyblR5cGUpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiB0eXBlIGFubm90YXRpb24gb24gcmVjb3JkIGRlY2xhcmF0aW9uXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiBkb2N1bWVudGVkLnR5cGVQYXJhbWV0ZXJzXG59XG5cbi8qKlxuICogUmV0dXJucyBhIG5hdGl2ZSBQSFAgdHlwZSBuYW1lIGZyb20gb25lIHN1cHBvcnRlZCBwYXJzZXIgbm9kZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlIHwgbnVsbH0gdHlwZSAtIE5hdGl2ZSB0eXBlIG5vZGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSBUeXBlIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHBocFR5cGVOYW1lKHR5cGUpIHtcbiAgaWYgKCF0eXBlIHx8ICFbXCJ0eXBlcmVmZXJlbmNlXCIsIFwibmFtZVwiLCBcImlkZW50aWZpZXJcIl0uaW5jbHVkZXModHlwZS5raW5kKSkgcmV0dXJuIHVuZGVmaW5lZFxuXG4gIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVHlwZVJlZmVyZW5jZSB8IGltcG9ydChcInBocC1wYXJzZXJcIikuTmFtZSB8IGltcG9ydChcInBocC1wYXJzZXJcIikuSWRlbnRpZmllcn0gKi8gKHR5cGUpLm5hbWVcbn1cblxuLyoqXG4gKiBXcmFwcyBvbmUgcGFyc2VyLWRlY2xhcmVkIGNhbm9uaWNhbCBQSFAgbnVsbGFibGUgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IHZhbHVlVHlwZSAtIFByZXNlbnQtdmFsdWUgc2VtYW50aWMgdHlwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlfSBzb3VyY2VUeXBlIC0gTmF0aXZlIHBhcnNlciB0eXBlIG5vZGUuXG4gKiBAcGFyYW0ge251bWJlcn0gb3duZXJTdGFydCAtIEVhcmxpZXN0IG93bmluZyBwYXJzZXIgb2Zmc2V0LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5PcHRpb25hbFR5cGV9IE9wdGlvbmFsIHNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIG51bGxhYmxlVHlwZSh2YWx1ZVR5cGUsIHNvdXJjZVR5cGUsIG93bmVyU3RhcnQsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKCFzb3VyY2VUeXBlLmxvYykgdGhyb3cgbmV3IEVycm9yKFwiUEhQIHBhcnNlciBvbWl0dGVkIG51bGxhYmxlIHR5cGUgbG9jYXRpb24uXCIpXG4gIGNvbnN0IHZhbHVlTG9jYXRpb24gPSBub2RlTG9jYXRpb24oc291cmNlVHlwZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbWFya2VyID0gdG9rZW5Mb2NhdGlvbihcIj9cIiwgb3duZXJTdGFydCwgc291cmNlVHlwZS5sb2Muc3RhcnQub2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChtYXJrZXIuZW5kLm9mZnNldCAhPSB2YWx1ZUxvY2F0aW9uLnN0YXJ0Lm9mZnNldCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbmNhbm9uaWNhbCBudWxsYWJsZSB0eXBlXCIsIG1hcmtlcilcbiAgfVxuXG4gIHJldHVybiBvcHRpb25hbFR5cGUoXG4gICAgdmFsdWVUeXBlLFxuICAgIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgbWFya2VyLnN0YXJ0Lm9mZnNldCwgdmFsdWVMb2NhdGlvbi5lbmQub2Zmc2V0KSxcbiAgICB2YWx1ZUxvY2F0aW9uXG4gIClcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhwbGljaXQgUEhQIGZ1bmN0aW9uIHJldHVybiB0eXBlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGUgfCBudWxsfSBzb3VyY2VUeXBlIC0gUEhQIHJldHVybiB0eXBlIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3ViamVjdCAtIFR5cGVkIGZ1bmN0aW9uIHJldHVybi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gRnVuY3Rpb24gbG9jYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uPn0gW3JlY29yZE5hbWVzXSAtIE5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBTZW1hbnRpYyByZXR1cm4gdHlwZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFJldHVyblR5cGUoc291cmNlVHlwZSwgc3ViamVjdCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghc291cmNlVHlwZSkgcmV0dXJuIHJlcXVpcmVTb3VyY2VSZXR1cm5UeXBlKFwicGhwXCIsIHVuZGVmaW5lZCwgc3ViamVjdCwgbG9jYXRpb24pXG4gIGlmIChzb3VyY2VUeXBlLmtpbmQgIT0gXCJ0eXBlcmVmZXJlbmNlXCIgJiYgc291cmNlVHlwZS5raW5kICE9IFwibmFtZVwiICYmIHNvdXJjZVR5cGUua2luZCAhPSBcImlkZW50aWZpZXJcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInVuc3VwcG9ydGVkIHJldHVybiB0eXBlXCIsIG5vZGVMb2NhdGlvbihzb3VyY2VUeXBlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCB0eXBlTmFtZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5UeXBlUmVmZXJlbmNlIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZGVudGlmaWVyfSAqLyAoc291cmNlVHlwZSkubmFtZVxuICBjb25zdCBkZWNsYXJhdGlvbiA9IHJlY29yZE5hbWVzLmdldCh0eXBlTmFtZSlcblxuICBpZiAoZGVjbGFyYXRpb24/LmlkKSByZXR1cm4gZGVjbGFyYXRpb24ua2luZCA9PSBcIkNsYXNzRGVjbGFyYXRpb25cIlxuICAgID8gcmVmZXJlbmNlVHlwZShkZWNsYXJhdGlvbi5pZCwgbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIDogZGVjbGFyYXRpb24ua2luZCA9PSBcIkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb25cIlxuICAgICAgPyBvd25lZFJlc291cmNlVHlwZShkZWNsYXJhdGlvbi5pZCwgbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgOiByZWNvcmRUeXBlKGRlY2xhcmF0aW9uLmlkLCBub2RlTG9jYXRpb24oc291cmNlVHlwZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG5cbiAgcmV0dXJuIHJlcXVpcmVTb3VyY2VSZXR1cm5UeXBlKFwicGhwXCIsIHR5cGVOYW1lLCBzdWJqZWN0LCBsb2NhdGlvbiwgbm9kZUxvY2F0aW9uKHNvdXJjZVR5cGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBleHBsaWNpdCB0eXBlIHNpZ25hdHVyZSBvZiBvbmUgUEhQIGZ1bmN0aW9uIGJlZm9yZSBhbnkgYm9keSBleHByZXNzaW9ucy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIFBIUCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3duZXJJZCAtIFN0YWJsZSBmdW5jdGlvbiBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtQaHBGdW5jdGlvblNpZ25hdHVyZX0gVHlwZWQgZnVuY3Rpb24gc2lnbmF0dXJlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0RnVuY3Rpb25TaWduYXR1cmUobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIG93bmVySWQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG5cbiAgaWYgKCFub2RlLmJvZHkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiBib2R5XCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgZG9jdW1lbnRlZCA9IGZ1bmN0aW9uRG9jdW1lbnRlZFR5cGVzKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIG93bmVySWQpXG4gIGNvbnN0IHR5cGVQYXJhbWV0ZXJOYW1lcyA9IG5ldyBNYXAoKGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnMgPz8gW10pLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlcl0pKVxuICBjb25zdCBwYXJhbWV0ZXJzID0gbm9kZS5hcmd1bWVudHMubWFwKChwYXJhbWV0ZXIpID0+IHtcbiAgICBjb25zdCBwYXJhbWV0ZXJMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgcGFyYW1ldGVyTmFtZSA9IHR5cGVvZiBwYXJhbWV0ZXIubmFtZSA9PSBcInN0cmluZ1wiID8gcGFyYW1ldGVyLm5hbWUgOiBwYXJhbWV0ZXIubmFtZS5uYW1lXG5cbiAgICBpZiAocGFyYW1ldGVyLmJ5cmVmKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJieS1yZWZlcmVuY2UgcGFyYW1ldGVyXCIsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChwYXJhbWV0ZXIudmFyaWFkaWMpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInZhcmlhZGljIHBhcmFtZXRlclwiLCBwYXJhbWV0ZXJMb2NhdGlvbilcbiAgICBpZiAocGFyYW1ldGVyLnZhbHVlKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkZWZhdWx0IHBhcmFtZXRlclwiLCBwYXJhbWV0ZXJMb2NhdGlvbilcbiAgICBjb25zdCBwYXJhbWV0ZXJOb2RlID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIgOiBwYXJhbWV0ZXIubmFtZVxuICAgIGNvbnN0IGRvY3VtZW50ZWRUeXBlID0gZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmdldChwYXJhbWV0ZXJOYW1lKVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSlcblxuICAgIGxldCBwYXJhbWV0ZXJUeXBlID0gZG9jdW1lbnRlZFR5cGVcbiAgICAgID8gZG9jdW1lbnRlZFZhbHVlVHlwZSh7bGFuZ3VhZ2U6IFwicGhwXCIsIGxvY2F0aW9uOiBkb2N1bWVudGVkVHlwZS5sb2NhdGlvbiwgb3duZXJMb2NhdGlvbjogcGFyYW1ldGVyTG9jYXRpb24sIHNvdXJjZSxcbiAgICAgICAgcmVjb3JkczogcmVjb3JkTmFtZXMsIHNvdXJjZVR5cGU6IGRvY3VtZW50ZWRUeXBlLnNvdXJjZVR5cGUsIHN1YmplY3Q6IGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgdHlwZVBhcmFtZXRlcnM6IHR5cGVQYXJhbWV0ZXJOYW1lc30pXG4gICAgICA6IGNvbnZlcnRUeXBlKHBhcmFtZXRlci50eXBlLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcylcblxuICAgIGlmIChuYXRpdmVUeXBlID09IFwiYXJyYXlcIiAmJiAhZG9jdW1lbnRlZFR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChkb2N1bWVudGVkVHlwZSAmJiAhcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIHBhcmFtZXRlci5udWxsYWJsZSwgcGFyYW1ldGVyVHlwZSwgcmVjb3JkTmFtZXMpKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJkb2N1bWVudGVkIHBhcmFtZXRlciB0eXBlIGluY29tcGF0aWJsZSB3aXRoIG5hdGl2ZSB0eXBlXCIsIGRvY3VtZW50ZWRUeXBlLmxvY2F0aW9uKVxuICAgIH1cblxuICAgIGlmIChwYXJhbWV0ZXIubnVsbGFibGUgJiYgcGFyYW1ldGVyVHlwZS5raW5kICE9IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICAgIGlmICghcGFyYW1ldGVyLnR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgICAgcGFyYW1ldGVyVHlwZSA9IG51bGxhYmxlVHlwZShwYXJhbWV0ZXJUeXBlLCBwYXJhbWV0ZXIudHlwZSwgcGFyYW1ldGVyLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSBlbHNlIGlmICghcGFyYW1ldGVyLm51bGxhYmxlICYmIHBhcmFtZXRlclR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiICYmXG4gICAgICBwYXJhbWV0ZXJUeXBlLnZhbHVlVHlwZS5raW5kICE9IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9wdGlvbmFsIGFubm90YXRpb24gd2l0aG91dCBudWxsYWJsZSBuYXRpdmUgdHlwZVwiLCBkb2N1bWVudGVkVHlwZT8ubG9jYXRpb24gPz8gcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHNlbWFudGljUGFyYW1ldGVyID0ge1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUGFyYW1ldGVyXCIpLFxuICAgICAgbG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgbmFtZTogcGFyYW1ldGVyTmFtZSxcbiAgICAgIHR5cGU6IHBhcmFtZXRlclR5cGVcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhzZW1hbnRpY1BhcmFtZXRlciwge25hbWU6IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXJOb2RlLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH0pXG4gIGNvbnN0IGV4dHJhRG9jdW1lbnRlZFBhcmFtZXRlciA9IFsuLi5kb2N1bWVudGVkLnBhcmFtZXRlcnMua2V5cygpXS5maW5kKChuYW1lKSA9PlxuICAgICFub2RlLmFyZ3VtZW50cy5zb21lKChwYXJhbWV0ZXIpID0+ICh0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZSkgPT0gbmFtZSkpXG5cbiAgaWYgKGV4dHJhRG9jdW1lbnRlZFBhcmFtZXRlcikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBhbm5vdGF0aW9uIGZvciB1bmtub3duIHBhcmFtZXRlciAnJHtleHRyYURvY3VtZW50ZWRQYXJhbWV0ZXJ9J2AsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5ieXJlZikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiYnktcmVmZXJlbmNlIHJldHVyblwiLCBsb2NhdGlvbilcbiAgY29uc3QgbmFtZU5vZGUgPSB0eXBlb2Ygbm9kZS5uYW1lID09IFwic3RyaW5nXCIgPyBub2RlIDogbm9kZS5uYW1lXG4gIGNvbnN0IG5hdGl2ZVJldHVyblR5cGUgPSBwaHBUeXBlTmFtZShub2RlLnR5cGUpXG4gIGxldCByZXR1cm5UeXBlXG5cbiAgaWYgKGRvY3VtZW50ZWQucmV0dXJuVHlwZSkge1xuICAgIHJldHVyblR5cGUgPSBkb2N1bWVudGVkVmFsdWVUeXBlKHtsYW5ndWFnZTogXCJwaHBcIiwgbG9jYXRpb246IGRvY3VtZW50ZWQucmV0dXJuVHlwZS5sb2NhdGlvbiwgb3duZXJMb2NhdGlvbjogbG9jYXRpb24sIHNvdXJjZSxcbiAgICAgIHJlY29yZHM6IHJlY29yZE5hbWVzLCBzb3VyY2VUeXBlOiBkb2N1bWVudGVkLnJldHVyblR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYEZ1bmN0aW9uICcke25hbWV9JyByZXR1cm5gLCB0eXBlUGFyYW1ldGVyczogdHlwZVBhcmFtZXRlck5hbWVzfSlcbiAgICBpZiAoIXBocERvY3VtZW50ZWROYXRpdmVUeXBlTWF0Y2hlcyhuYXRpdmVSZXR1cm5UeXBlLCBub2RlLm51bGxhYmxlLCByZXR1cm5UeXBlLCByZWNvcmROYW1lcykpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImRvY3VtZW50ZWQgcmV0dXJuIHR5cGUgaW5jb21wYXRpYmxlIHdpdGggbmF0aXZlIHR5cGVcIiwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobmF0aXZlUmV0dXJuVHlwZSA9PSBcImFycmF5XCIpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgRnVuY3Rpb24gJyR7bmFtZX0nIHJldHVybmAsIGxvY2F0aW9uKVxuICAgIHJldHVyblR5cGUgPSBjb252ZXJ0UmV0dXJuVHlwZShub2RlLnR5cGUsIGBGdW5jdGlvbiAnJHtuYW1lfScgcmV0dXJuYCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzKVxuICB9XG4gIGlmIChub2RlLm51bGxhYmxlICYmIHJldHVyblR5cGUua2luZCAhPSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKCFub2RlLnR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgRnVuY3Rpb24gJyR7bmFtZX0nIHJldHVybmAsIGxvY2F0aW9uKVxuICAgIGNvbnN0IHR5cGVTdGFydCA9IG5vZGUudHlwZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwXG5cbiAgICByZXR1cm5UeXBlID0gbnVsbGFibGVUeXBlKFxuICAgICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gKi8gKHJldHVyblR5cGUpLFxuICAgICAgbm9kZS50eXBlLFxuICAgICAgTWF0aC5tYXgobm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCB0eXBlU3RhcnQgLSAyKSxcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgc291cmNlXG4gICAgKVxuICB9IGVsc2UgaWYgKCFub2RlLm51bGxhYmxlICYmIHJldHVyblR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiICYmXG4gICAgcmV0dXJuVHlwZS52YWx1ZVR5cGUua2luZCAhPSBcIlR5cGVWYXJpYWJsZVJlZmVyZW5jZVwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwib3B0aW9uYWwgYW5ub3RhdGlvbiB3aXRob3V0IG51bGxhYmxlIG5hdGl2ZSByZXR1cm4gdHlwZVwiLCBkb2N1bWVudGVkLnJldHVyblR5cGU/LmxvY2F0aW9uID8/IGxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBsb2NhdGlvbixcbiAgICBuYW1lLFxuICAgIG5hbWVMb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5hbWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBwYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGUsXG4gICAgLi4uKGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnN9IDoge30pXG4gIH1cbn1cblxuLyoqXG4gKiBDaGVja3MgdGhlIGV4YWN0IHJ1bnRpbWUgY2FycmllciBwZXJtaXR0ZWQgYmVzaWRlIGEgcHJlY2lzZSBQSFBEb2MgdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSBuYXRpdmVUeXBlIC0gTmF0aXZlIFBIUCB0eXBlIG5hbWUuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IG5hdGl2ZU51bGxhYmxlIC0gV2hldGhlciB0aGUgbmF0aXZlIGNhcnJpZXIgaGFzIFBIUCdzIG51bGxhYmxlIG1hcmtlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IGRvY3VtZW50ZWRUeXBlIC0gRXhhY3Qgc2VtYW50aWMgZG9jdW1lbnQgdHlwZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZHMgLSBWaXNpYmxlIG5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IG5hbWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbmF0aXZlIGNhcnJpZXIgYWdyZWVzIHdpdGhvdXQgY2hhbmdpbmcgbWVhbmluZy5cbiAqL1xuZnVuY3Rpb24gcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIG5hdGl2ZU51bGxhYmxlLCBkb2N1bWVudGVkVHlwZSwgcmVjb3Jkcykge1xuICBpZiAoZG9jdW1lbnRlZFR5cGUua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKGRvY3VtZW50ZWRUeXBlLnZhbHVlVHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICAgIHJldHVybiBuYXRpdmVUeXBlID09PSB1bmRlZmluZWQgJiYgIW5hdGl2ZU51bGxhYmxlXG4gICAgfVxuXG4gICAgcmV0dXJuIG5hdGl2ZU51bGxhYmxlICYmIHBocERvY3VtZW50ZWROYXRpdmVUeXBlTWF0Y2hlcyhuYXRpdmVUeXBlLCBmYWxzZSwgZG9jdW1lbnRlZFR5cGUudmFsdWVUeXBlLCByZWNvcmRzKVxuICB9XG4gIGlmIChuYXRpdmVOdWxsYWJsZSkgcmV0dXJuIGZhbHNlXG4gIGlmIChkb2N1bWVudGVkVHlwZS5raW5kID09IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHJldHVybiBuYXRpdmVUeXBlID09PSB1bmRlZmluZWRcbiAgaWYgKGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJUeXBlUmVmZXJlbmNlXCIpIHtcbiAgICByZXR1cm4gbmF0aXZlVHlwZSAhPT0gdW5kZWZpbmVkICYmIHNvdXJjZVNjYWxhclR5cGUoXCJwaHBcIiwgbmF0aXZlVHlwZSk/Lm5hbWUgPT0gZG9jdW1lbnRlZFR5cGUubmFtZVxuICB9XG4gIGlmIChkb2N1bWVudGVkVHlwZS5raW5kID09IFwiTGlzdFR5cGVcIiB8fCBkb2N1bWVudGVkVHlwZS5raW5kID09IFwiTWFwVHlwZVwiIHx8IGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgcmV0dXJuIG5hdGl2ZVR5cGUgPT0gXCJhcnJheVwiXG4gIH1cbiAgaWYgKGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIpIHtcbiAgICByZXR1cm4gbmF0aXZlVHlwZSAhPT0gdW5kZWZpbmVkICYmIHJlY29yZHMuZ2V0KG5hdGl2ZVR5cGUpPy5pZCA9PSBkb2N1bWVudGVkVHlwZS5kZWNsYXJhdGlvbklkXG4gIH1cbiAgaWYgKGRvY3VtZW50ZWRUeXBlLmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICByZXR1cm4gbmF0aXZlVHlwZSAhPT0gdW5kZWZpbmVkICYmIHJlY29yZHMuZ2V0KG5hdGl2ZVR5cGUpPy5pZCA9PSBkb2N1bWVudGVkVHlwZS5kZWNsYXJhdGlvbklkXG4gIH1cblxuICByZXR1cm4gZmFsc2Vcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIFBIUCBmdW5jdGlvbiBib2R5IHVzaW5nIHRoZSBhbHJlYWR5LXByb3ZlZCBtb2R1bGUgc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gbm9kZSAtIFBIUCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtQaHBGdW5jdGlvblNpZ25hdHVyZX0gc2lnbmF0dXJlIC0gUHJlY29udmVydGVkIGV4cGxpY2l0IHNpZ25hdHVyZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgUGhwRnVuY3Rpb25TaWduYXR1cmU+fSBmdW5jdGlvbnMgLSBNb2R1bGUgZnVuY3Rpb24gc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPn0gcmVjb3JkcyAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBjbGFzc2VzIC0gUmVmZXJlbmNlIGNsYXNzZXMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvck5hbWVzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gZXJyb3JzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uKG5vZGUsIHNpZ25hdHVyZSwgZnVuY3Rpb25zLCByZWNvcmROYW1lcywgcmVjb3JkcywgY2xhc3NlcywgZXJyb3JOYW1lcywgZXJyb3JzLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICghbm9kZS5ib2R5KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJmdW5jdGlvbiBib2R5XCIsIHNpZ25hdHVyZS5sb2NhdGlvbilcbiAgY29uc3QgY29udGV4dCA9IHtcbiAgICBiaW5kaW5nczogbmV3IE1hcChzaWduYXR1cmUucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gW3BhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXIudHlwZV0pKSxcbiAgICBjbGFzc2VzLFxuICAgIGVycm9yTmFtZXMsXG4gICAgZXJyb3JzLFxuICAgIGZ1bmN0aW9ucyxcbiAgICBvcmRlcmVkTWFwRGVjbGFyYXRpb25zOiBvcmRlcmVkTWFwRGVjbGFyYXRpb25zRm9yUGhwKG5vZGUuYm9keSksXG4gICAgcmVjb3JkTmFtZXMsXG4gICAgcmVjb3JkcyxcbiAgICByZXR1cm5UeXBlOiBzaWduYXR1cmUucmV0dXJuVHlwZSxcbiAgICB0eXBlUGFyYW1ldGVyczogbmV3IE1hcCgoc2lnbmF0dXJlLnR5cGVQYXJhbWV0ZXJzID8/IFtdKS5tYXAoKHBhcmFtZXRlcikgPT4gW3BhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXJdKSlcbiAgfVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBib2R5OiBjb252ZXJ0QmxvY2sobm9kZS5ib2R5LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICBraW5kOiBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIixcbiAgICBsb2NhdGlvbjogc2lnbmF0dXJlLmxvY2F0aW9uLFxuICAgIG5hbWU6IHNpZ25hdHVyZS5uYW1lLFxuICAgIHBhcmFtZXRlcnM6IHNpZ25hdHVyZS5wYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGU6IHNpZ25hdHVyZS5yZXR1cm5UeXBlLFxuICAgIC4uLihzaWduYXR1cmUudHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IHNpZ25hdHVyZS50eXBlUGFyYW1ldGVyc30gOiB7fSlcbiAgfSwge25hbWU6IHNpZ25hdHVyZS5uYW1lTG9jYXRpb259KVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHBhcnNlci1vd25lZCBrZXkvdmFsdWUgbG9vcHMgdG8gZXhhY3QgZGVjbGFyYXRpb25zIGluc2lkZSBvbmUgbGV4aWNhbCBvd25lci5cbiAqIEFtYmlndW91cyBzYW1lLW5hbWUgZGVjbGFyYXRpb25zIHByb2R1Y2Ugbm8gZXZpZGVuY2UgYW5kIGZhaWwgZHVyaW5nIGxvb3AgY29udmVyc2lvbi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBGdW5jdGlvbiBib2R5IG9yIGVudHJ5LXBvaW50IHN1YnRyZWUuXG4gKiBAcmV0dXJucyB7U2V0PG9iamVjdD59IEV4YWN0IHBhaXItaXRlcmF0ZWQgcGFyc2VyIGRlY2xhcmF0aW9ucy5cbiAqL1xuZnVuY3Rpb24gb3JkZXJlZE1hcERlY2xhcmF0aW9uc0ZvclBocCh2YWx1ZSkge1xuICAvKiogQHR5cGUge3tkZWNsYXJhdGlvbjogb2JqZWN0LCBuYW1lOiBzdHJpbmcsIG9mZnNldDogbnVtYmVyfVtdfSAqL1xuICBjb25zdCBkZWNsYXJhdGlvbnMgPSBbXVxuICAvKiogQHR5cGUge3tuYW1lOiBzdHJpbmcsIG9mZnNldDogbnVtYmVyfVtdfSAqL1xuICBjb25zdCByZWNlaXZlcnMgPSBbXVxuICBjb25zdCBzZWVuID0gbmV3IFdlYWtTZXQoKVxuICAvKipcbiAgICogVmlzaXRzIG9uZSBwYXJzZXIgY2FuZGlkYXRlLlxuICAgKiBAcGFyYW0ge3Vua25vd259IGNhbmRpZGF0ZSAtIFBhcnNlciBjYW5kaWRhdGUuXG4gICAqL1xuICBjb25zdCB2aXNpdCA9IChjYW5kaWRhdGUpID0+IHtcbiAgICBpZiAoIWNhbmRpZGF0ZSB8fCB0eXBlb2YgY2FuZGlkYXRlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXMoY2FuZGlkYXRlKSkgcmV0dXJuXG4gICAgc2Vlbi5hZGQoY2FuZGlkYXRlKVxuICAgIGNvbnN0IGtpbmQgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwia2luZFwiKVxuXG4gICAgaWYgKGtpbmQgPT0gXCJmdW5jdGlvblwiIHx8IGtpbmQgPT0gXCJjbGFzc1wiKSByZXR1cm5cbiAgICBpZiAoa2luZCA9PSBcImFzc2lnblwiKSB7XG4gICAgICBjb25zdCB2YXJpYWJsZSA9IFJlZmxlY3QuZ2V0KGNhbmRpZGF0ZSwgXCJsZWZ0XCIpXG5cbiAgICAgIGlmIChSZWZsZWN0LmdldCh2YXJpYWJsZSwgXCJraW5kXCIpID09IFwidmFyaWFibGVcIiAmJiB0eXBlb2YgUmVmbGVjdC5nZXQodmFyaWFibGUsIFwibmFtZVwiKSA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIGRlY2xhcmF0aW9ucy5wdXNoKHtcbiAgICAgICAgICBkZWNsYXJhdGlvbjogY2FuZGlkYXRlLFxuICAgICAgICAgIG5hbWU6IFJlZmxlY3QuZ2V0KHZhcmlhYmxlLCBcIm5hbWVcIiksXG4gICAgICAgICAgb2Zmc2V0OiBSZWZsZWN0LmdldCh2YXJpYWJsZSwgXCJsb2NcIik/LnN0YXJ0Lm9mZnNldFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoa2luZCA9PSBcImZvcmVhY2hcIikge1xuICAgICAgY29uc3QgcmVjZWl2ZXIgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwic291cmNlXCIpXG5cbiAgICAgIGlmIChSZWZsZWN0LmdldChyZWNlaXZlciwgXCJraW5kXCIpID09IFwidmFyaWFibGVcIiAmJiB0eXBlb2YgUmVmbGVjdC5nZXQocmVjZWl2ZXIsIFwibmFtZVwiKSA9PSBcInN0cmluZ1wiICYmXG4gICAgICAgIFJlZmxlY3QuZ2V0KGNhbmRpZGF0ZSwgXCJrZXlcIikpIHJlY2VpdmVycy5wdXNoKHtcbiAgICAgICAgbmFtZTogUmVmbGVjdC5nZXQocmVjZWl2ZXIsIFwibmFtZVwiKSxcbiAgICAgICAgb2Zmc2V0OiBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwibG9jXCIpPy5zdGFydC5vZmZzZXRcbiAgICAgIH0pXG4gICAgfVxuICAgIGZvciAoY29uc3QgW2tleSwgY2hpbGRdIG9mIE9iamVjdC5lbnRyaWVzKGNhbmRpZGF0ZSkpIHtcbiAgICAgIGlmIChbXCJsb2NcIiwgXCJsZWFkaW5nQ29tbWVudHNcIiwgXCJ0cmFpbGluZ0NvbW1lbnRzXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZCkpIHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGNoaWxkKSB2aXNpdChpdGVtKVxuICAgICAgfSBlbHNlIHZpc2l0KGNoaWxkKVxuICAgIH1cbiAgfVxuXG4gIHZpc2l0KHZhbHVlKVxuICBjb25zdCBzZWxlY3RlZCA9IG5ldyBTZXQoKVxuICBmb3IgKGNvbnN0IHJlY2VpdmVyIG9mIHJlY2VpdmVycykge1xuICAgIGNvbnN0IG1hdGNoZXMgPSBkZWNsYXJhdGlvbnMuZmlsdGVyKCh7bmFtZSwgb2Zmc2V0fSkgPT4gbmFtZSA9PSByZWNlaXZlci5uYW1lICYmIG9mZnNldCA8IHJlY2VpdmVyLm9mZnNldClcblxuICAgIGlmIChtYXRjaGVzLmxlbmd0aCA9PSAxKSBzZWxlY3RlZC5hZGQobWF0Y2hlc1swXS5kZWNsYXJhdGlvbilcbiAgfVxuXG4gIHJldHVybiBzZWxlY3RlZFxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBmaW5hbCBSdW50aW1lRXhjZXB0aW9uIHN1YmNsYXNzLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNsYXNzfSBub2RlIC0gUEhQIGNsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFByZWRlY2xhcmVkIHNlbWFudGljIGVycm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSBTZW1hbnRpYyBlcnJvciBkZWNsYXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydFBocEVycm9yKG5vZGUsIGRlY2xhcmF0aW9uLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IHBhcmVudCA9IG5vZGUuZXh0ZW5kc1xuICBjb25zdCBwYXJlbnROYW1lID0gcGFyZW50Py5raW5kID09IFwibmFtZVwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWV9ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChwYXJlbnQpKSA6IHVuZGVmaW5lZFxuXG4gIGlmIChub2RlLmlzQW5vbnltb3VzIHx8ICFub2RlLmlzRmluYWwgfHwgbm9kZS5pc1JlYWRvbmx5IHx8IG5vZGUuaXNBYnN0cmFjdCB8fCBub2RlLmltcGxlbWVudHM/Lmxlbmd0aCB8fFxuICAgIG5vZGUuYXR0ckdyb3Vwcy5sZW5ndGggfHwgbm9kZS5ib2R5Lmxlbmd0aCAhPSAwIHx8ICFwYXJlbnROYW1lIHx8XG4gICAgIShwYXJlbnROYW1lLm5hbWUgPT0gXCJSdW50aW1lRXhjZXB0aW9uXCIgJiYgcGFyZW50TmFtZS5yZXNvbHV0aW9uID09IFwidXFuXCIgfHxcbiAgICAgIHBhcmVudE5hbWUubmFtZSA9PSBcIlxcXFxSdW50aW1lRXhjZXB0aW9uXCIgJiYgcGFyZW50TmFtZS5yZXNvbHV0aW9uID09IFwiZnFuXCIpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHR5cGVkIGVycm9yIGRlY2xhcmF0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IG5hbWVOb2RlID0gdHlwZW9mIG5vZGUubmFtZSA9PSBcInN0cmluZ1wiID8gbm9kZSA6IG5vZGUubmFtZVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKGRlY2xhcmF0aW9uLCB7bmFtZTogbm9kZUxvY2F0aW9uKG5hbWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSwgdHlwZTogbm9kZUxvY2F0aW9uKHBhcmVudE5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBSZWFkcyBvbmUgZXhhY3QgcHVibGljIFBIUCBjb25zdHJ1Y3RvciBvciBpbnN0YW5jZS1tZXRob2Qgc2lnbmF0dXJlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk1ldGhvZH0gbm9kZSAtIFBhcnNlci1vd25lZCBtZXRob2QuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSBub21pbmFsTmFtZXMgLSBWaXNpYmxlIG5vbWluYWwgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IG93bmVySWQgLSBTdGFibGUgY2FsbGFibGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNvbnN0cnVjdG9yIC0gV2hldGhlciB0aGlzIGlzIHRoZSBzb2xlIGNvbnN0cnVjdG9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBuYW1lOiBzdHJpbmcsIG5hbWVMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHBhcmFtZXRlcnM6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdLCByZXR1cm5UeXBlPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9fSBFeGFjdCBzaWduYXR1cmUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRQaHBDbGFzc0NhbGxhYmxlU2lnbmF0dXJlKG5vZGUsIG5vbWluYWxOYW1lcywgb3duZXJJZCwgY29uc3RydWN0b3IsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG5cbiAgaWYgKCFjb25zdHJ1Y3RvciAmJiAvXl9fL3UudGVzdChuYW1lKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGByZXNlcnZlZCByZWZlcmVuY2UgbWV0aG9kICcke25hbWV9J2AsIGxvY2F0aW9uKVxuICBpZiAobm9kZS52aXNpYmlsaXR5ICE9IFwicHVibGljXCIgfHwgbm9kZS5pc1N0YXRpYyB8fCBub2RlLmlzQWJzdHJhY3QgfHwgbm9kZS5pc0ZpbmFsIHx8IFJlZmxlY3QuZ2V0KG5vZGUsIFwiaXNSZWFkb25seVwiKSB8fCBub2RlLmJ5cmVmIHx8XG4gICAgbm9kZS5hdHRyR3JvdXBzLmxlbmd0aCB8fCAhbm9kZS5ib2R5IHx8IGNvbnN0cnVjdG9yICE9IChuYW1lID09IFwiX19jb25zdHJ1Y3RcIikpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJub25jYW5vbmljYWwgcmVmZXJlbmNlIGNsYXNzIGNhbGxhYmxlXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGRvY3VtZW50ZWQgPSBmdW5jdGlvbkRvY3VtZW50ZWRUeXBlcygvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChub2RlKSksXG4gICAgZmlsZW5hbWUsIHNvdXJjZSwgb3duZXJJZClcbiAgaWYgKGRvY3VtZW50ZWQudHlwZVBhcmFtZXRlcnM/Lmxlbmd0aCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZ2VuZXJpYyByZWZlcmVuY2UgY2xhc3MgY2FsbGFibGVcIiwgbG9jYXRpb24pXG4gIGlmIChjb25zdHJ1Y3RvciAmJiAobm9kZS50eXBlIHx8IG5vZGUubnVsbGFibGUgfHwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImNvbnN0cnVjdG9yIHJldHVybiBhbm5vdGF0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IHBhcmFtZXRlcnMgPSBub2RlLmFyZ3VtZW50cy5tYXAoKHBhcmFtZXRlcikgPT4ge1xuICAgIGNvbnN0IHBhcmFtZXRlckxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKHBhcmFtZXRlciwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBwYXJhbWV0ZXJOYW1lID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIubmFtZSA6IHBhcmFtZXRlci5uYW1lLm5hbWVcblxuICAgIGlmIChwYXJhbWV0ZXIuYnlyZWYgfHwgcGFyYW1ldGVyLnZhcmlhZGljIHx8IHBhcmFtZXRlci52YWx1ZSB8fCBwYXJhbWV0ZXIuZmxhZ3MgfHwgcGFyYW1ldGVyLnJlYWRvbmx5IHx8XG4gICAgICBwYXJhbWV0ZXIuaG9va3MubGVuZ3RoIHx8IHBhcmFtZXRlci5hdHRyR3JvdXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHJlZmVyZW5jZSBjbGFzcyBwYXJhbWV0ZXJcIiwgcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IGRvY3VtZW50ZWRUeXBlID0gZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmdldChwYXJhbWV0ZXJOYW1lKVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSlcbiAgICBsZXQgdHlwZSA9IGRvY3VtZW50ZWRUeXBlXG4gICAgICA/IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZFR5cGUubG9jYXRpb24sIG93bmVyTG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgICByZWNvcmRzOiBub21pbmFsTmFtZXMsIHNvdXJjZSwgc291cmNlVHlwZTogZG9jdW1lbnRlZFR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYFBhcmFtZXRlciAnJHtwYXJhbWV0ZXJOYW1lfSdgfSlcbiAgICAgIDogY29udmVydFR5cGUocGFyYW1ldGVyLnR5cGUsIGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIG5vbWluYWxOYW1lcylcblxuICAgIGlmIChuYXRpdmVUeXBlID09IFwiYXJyYXlcIiAmJiAhZG9jdW1lbnRlZFR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlck5hbWV9J2AsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChkb2N1bWVudGVkVHlwZSAmJiAhcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIHBhcmFtZXRlci5udWxsYWJsZSwgdHlwZSwgbm9taW5hbE5hbWVzKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZG9jdW1lbnRlZCBwYXJhbWV0ZXIgdHlwZSBpbmNvbXBhdGlibGUgd2l0aCBuYXRpdmUgdHlwZVwiLCBkb2N1bWVudGVkVHlwZS5sb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKHBhcmFtZXRlci5udWxsYWJsZSAmJiB0eXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgaWYgKCFwYXJhbWV0ZXIudHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgICB0eXBlID0gbnVsbGFibGVUeXBlKHR5cGUsIHBhcmFtZXRlci50eXBlLCBwYXJhbWV0ZXIubG9jPy5zdGFydC5vZmZzZXQgPz8gMCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9IGVsc2UgaWYgKCFwYXJhbWV0ZXIubnVsbGFibGUgJiYgdHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9wdGlvbmFsIGFubm90YXRpb24gd2l0aG91dCBudWxsYWJsZSBuYXRpdmUgdHlwZVwiLCBkb2N1bWVudGVkVHlwZT8ubG9jYXRpb24gPz8gcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IG5hbWVOb2RlID0gdHlwZW9mIHBhcmFtZXRlci5uYW1lID09IFwic3RyaW5nXCIgPyBwYXJhbWV0ZXIgOiBwYXJhbWV0ZXIubmFtZVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHBhcmFtZXRlckxvY2F0aW9uLFxuICAgICAgbmFtZTogcGFyYW1ldGVyTmFtZSwgdHlwZX0sIHtuYW1lOiBub2RlTG9jYXRpb24obmFtZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfSlcbiAgaWYgKFsuLi5kb2N1bWVudGVkLnBhcmFtZXRlcnMua2V5cygpXS5zb21lKChwYXJhbWV0ZXJOYW1lKSA9PlxuICAgICFub2RlLmFyZ3VtZW50cy5zb21lKChwYXJhbWV0ZXIpID0+ICh0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZSkgPT0gcGFyYW1ldGVyTmFtZSkpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWV0aG9kIFBIUERvYyBwYXJhbWV0ZXIgbWlzbWF0Y2hcIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgbmFtZU5vZGUgPSB0eXBlb2Ygbm9kZS5uYW1lID09IFwic3RyaW5nXCIgPyBub2RlIDogbm9kZS5uYW1lXG5cbiAgaWYgKGNvbnN0cnVjdG9yKSByZXR1cm4ge2xvY2F0aW9uLCBuYW1lOiBcImNvbnN0cnVjdG9yXCIsIG5hbWVMb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5hbWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSwgcGFyYW1ldGVyc31cbiAgbGV0IHJldHVyblR5cGVcbiAgY29uc3QgbmF0aXZlUmV0dXJuVHlwZSA9IHBocFR5cGVOYW1lKG5vZGUudHlwZSlcblxuICBpZiAoZG9jdW1lbnRlZC5yZXR1cm5UeXBlKSB7XG4gICAgcmV0dXJuVHlwZSA9IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uLCBvd25lckxvY2F0aW9uOiBsb2NhdGlvbixcbiAgICAgIHJlY29yZHM6IG5vbWluYWxOYW1lcywgc291cmNlLCBzb3VyY2VUeXBlOiBkb2N1bWVudGVkLnJldHVyblR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYE1ldGhvZCAnJHtuYW1lfScgcmV0dXJuYH0pXG4gICAgaWYgKCFwaHBEb2N1bWVudGVkTmF0aXZlVHlwZU1hdGNoZXMobmF0aXZlUmV0dXJuVHlwZSwgbm9kZS5udWxsYWJsZSwgcmV0dXJuVHlwZSwgbm9taW5hbE5hbWVzKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZG9jdW1lbnRlZCBtZXRob2QgcmV0dXJuIHR5cGUgaW5jb21wYXRpYmxlIHdpdGggbmF0aXZlIHR5cGVcIiwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uKVxuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBpZiAobmF0aXZlUmV0dXJuVHlwZSA9PSBcImFycmF5XCIpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbilcbiAgICByZXR1cm5UeXBlID0gY29udmVydFJldHVyblR5cGUobm9kZS50eXBlLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgbm9taW5hbE5hbWVzKVxuICB9XG4gIGlmIChub2RlLm51bGxhYmxlICYmIHJldHVyblR5cGUua2luZCAhPSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgaWYgKCFub2RlLnR5cGUpIHJldHVybiBtaXNzaW5nVHlwZShcInBocFwiLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbilcbiAgICByZXR1cm5UeXBlID0gbnVsbGFibGVUeXBlKC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9ICovIChyZXR1cm5UeXBlKSwgbm9kZS50eXBlLFxuICAgICAgbm9kZS50eXBlLmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0gZWxzZSBpZiAoIW5vZGUubnVsbGFibGUgJiYgcmV0dXJuVHlwZS5raW5kID09IFwiT3B0aW9uYWxUeXBlXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJvcHRpb25hbCBhbm5vdGF0aW9uIHdpdGhvdXQgbnVsbGFibGUgbmF0aXZlIHJldHVybiB0eXBlXCIsIGRvY3VtZW50ZWQucmV0dXJuVHlwZT8ubG9jYXRpb24gPz8gbG9jYXRpb24pXG4gIH1cblxuICByZXR1cm4ge2xvY2F0aW9uLCBuYW1lLCBuYW1lTG9jYXRpb246IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksIHBhcmFtZXRlcnMsIHJldHVyblR5cGV9XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGJvdW5kZWQgZmluYWwvcHJpdmF0ZS1maWVsZCBQSFAgcmVmZXJlbmNlLWNsYXNzIHByb2ZpbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2xhc3N9IG5vZGUgLSBQYXJzZXIgY2xhc3MuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gUHJlZGVjbGFyZWQgY2xhc3MgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSBub21pbmFsTmFtZXMgLSBWaXNpYmxlIG5vbWluYWwgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IHJlY29yZHMgLSBSZWNvcmRzIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gY2xhc3NlcyAtIENsYXNzZXMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIFBocEZ1bmN0aW9uU2lnbmF0dXJlPn0gZnVuY3Rpb25zIC0gVG9wLWxldmVsIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvck5hbWVzIC0gRXJyb3JzIGJ5IG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvcnMgLSBFcnJvcnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb259IFNlbWFudGljIGNsYXNzLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGhwUmVmZXJlbmNlQ2xhc3Mobm9kZSwgZGVjbGFyYXRpb24sIG5vbWluYWxOYW1lcywgcmVjb3JkcywgY2xhc3NlcywgZnVuY3Rpb25zLCBlcnJvck5hbWVzLCBlcnJvcnMsXG4gIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5pc0Fub255bW91cyB8fCAhbm9kZS5pc0ZpbmFsIHx8IG5vZGUuaXNSZWFkb25seSB8fCBub2RlLmlzQWJzdHJhY3QgfHwgbm9kZS5leHRlbmRzIHx8IG5vZGUuaW1wbGVtZW50cz8ubGVuZ3RoIHx8XG4gICAgbm9kZS5hdHRyR3JvdXBzLmxlbmd0aCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicmVmZXJlbmNlIGNsYXNzIGluaGVyaXRhbmNlIG9yIG5vbmNhbm9uaWNhbCBtb2RpZmllclwiLCBsb2NhdGlvbilcbiAgY29uc3QgZmllbGRTdGF0ZW1lbnRzID0gbm9kZS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIua2luZCA9PSBcInByb3BlcnR5c3RhdGVtZW50XCIpXG4gIGNvbnN0IG1ldGhvZE5vZGVzID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk1ldGhvZFtdfSAqLyAobm9kZS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIua2luZCA9PSBcIm1ldGhvZFwiKSlcbiAgY29uc3QgY29uc3RydWN0b3JzID0gbWV0aG9kTm9kZXMuZmlsdGVyKChtZXRob2QpID0+ICh0eXBlb2YgbWV0aG9kLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG1ldGhvZC5uYW1lIDogbWV0aG9kLm5hbWUubmFtZSkgPT0gXCJfX2NvbnN0cnVjdFwiKVxuICBjb25zdCBvcmRpbmFyeU1ldGhvZHMgPSBtZXRob2ROb2Rlcy5maWx0ZXIoKG1ldGhvZCkgPT4gIWNvbnN0cnVjdG9ycy5pbmNsdWRlcyhtZXRob2QpKVxuXG4gIGlmIChjb25zdHJ1Y3RvcnMubGVuZ3RoICE9IDEgfHwgZmllbGRTdGF0ZW1lbnRzLmxlbmd0aCA9PSAwIHx8IGZpZWxkU3RhdGVtZW50cy5sZW5ndGggKyBtZXRob2ROb2Rlcy5sZW5ndGggIT0gbm9kZS5ib2R5Lmxlbmd0aCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInJlZmVyZW5jZSBjbGFzcyByZXF1aXJlcyBwcml2YXRlIGZpZWxkcywgb25lIGNvbnN0cnVjdG9yLCBhbmQgb3JkaW5hcnkgbWV0aG9kc1wiLCBsb2NhdGlvbilcbiAgfVxuICBkZWNsYXJhdGlvbi5maWVsZHMgPSBmaWVsZFN0YXRlbWVudHMubWFwKChzdGF0ZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgZmllbGRMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihzdGF0ZW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgcHJvcGVydGllcyA9IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJwcm9wZXJ0aWVzXCIpXG4gICAgY29uc3QgcHJvcGVydHkgPSBBcnJheS5pc0FycmF5KHByb3BlcnRpZXMpICYmIHByb3BlcnRpZXMubGVuZ3RoID09IDEgPyBwcm9wZXJ0aWVzWzBdIDogdW5kZWZpbmVkXG4gICAgY29uc3QgbmFtZU5vZGUgPSBwcm9wZXJ0eT8ubmFtZVxuICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgbmFtZU5vZGUgPT0gXCJzdHJpbmdcIiA/IG5hbWVOb2RlIDogbmFtZU5vZGU/Lm5hbWVcblxuICAgIGlmIChSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwidmlzaWJpbGl0eVwiKSAhPSBcInByaXZhdGVcIiB8fCBSZWZsZWN0LmdldChzdGF0ZW1lbnQsIFwiaXNTdGF0aWNcIikgfHxcbiAgICAgIFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJpc0Fic3RyYWN0XCIpIHx8IFJlZmxlY3QuZ2V0KHN0YXRlbWVudCwgXCJpc0ZpbmFsXCIpIHx8ICFwcm9wZXJ0eSB8fFxuICAgICAgdHlwZW9mIG5hbWUgIT0gXCJzdHJpbmdcIiB8fCBwcm9wZXJ0eS52YWx1ZSB8fCBwcm9wZXJ0eS5yZWFkb25seSB8fCBwcm9wZXJ0eS5udWxsYWJsZSB8fCBwcm9wZXJ0eS5hdHRyR3JvdXBzPy5sZW5ndGggfHxcbiAgICAgIHByb3BlcnR5Lmhvb2tzPy5sZW5ndGgpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm5vbmNhbm9uaWNhbCBwcml2YXRlIGluc3RhbmNlIGZpZWxkXCIsIGZpZWxkTG9jYXRpb24pXG4gICAgY29uc3QgdHlwZSA9IGNvbnZlcnRUeXBlKHByb3BlcnR5LnR5cGUsIGBQcml2YXRlIGZpZWxkICcke25hbWV9J2AsIGZpZWxkTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIG5vbWluYWxOYW1lcylcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtpZDogYCR7ZGVjbGFyYXRpb24uaWR9OmZpZWxkOiR7aW5kZXh9YCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUHJpdmF0ZUZpZWxkXCIpLFxuICAgICAgbG9jYXRpb246IGZpZWxkTG9jYXRpb24sIG5hbWUsIHR5cGV9LCB7bmFtZTogbm9kZUxvY2F0aW9uKHR5cGVvZiBuYW1lTm9kZSA9PSBcInN0cmluZ1wiID8gcHJvcGVydHkgOiBuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9KVxuICBjb25zdCBjb25zdHJ1Y3Rvck5vZGUgPSBjb25zdHJ1Y3RvcnNbMF1cbiAgY29uc3QgY29uc3RydWN0b3JTaWduYXR1cmUgPSBjb252ZXJ0UGhwQ2xhc3NDYWxsYWJsZVNpZ25hdHVyZShjb25zdHJ1Y3Rvck5vZGUsIG5vbWluYWxOYW1lcyxcbiAgICBgJHtkZWNsYXJhdGlvbi5pZH06Y29uc3RydWN0b3JgLCB0cnVlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yID0gd2l0aFBhcnNlclJhbmdlcyh7Ym9keTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKHt9KSxcbiAgICBpZDogYCR7ZGVjbGFyYXRpb24uaWR9OmNvbnN0cnVjdG9yYCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQ29uc3RydWN0b3JEZWNsYXJhdGlvblwiKSxcbiAgICBsb2NhdGlvbjogY29uc3RydWN0b3JTaWduYXR1cmUubG9jYXRpb24sIHBhcmFtZXRlcnM6IGNvbnN0cnVjdG9yU2lnbmF0dXJlLnBhcmFtZXRlcnN9LCB7Y29uc3RydWN0b3I6IGNvbnN0cnVjdG9yU2lnbmF0dXJlLm5hbWVMb2NhdGlvbn0pXG4gIGNvbnN0IG1ldGhvZFNpZ25hdHVyZXMgPSBvcmRpbmFyeU1ldGhvZHMubWFwKChtZXRob2QsIGluZGV4KSA9PiBjb252ZXJ0UGhwQ2xhc3NDYWxsYWJsZVNpZ25hdHVyZShtZXRob2QsIG5vbWluYWxOYW1lcyxcbiAgICBgJHtkZWNsYXJhdGlvbi5pZH06bWV0aG9kOiR7aW5kZXh9YCwgZmFsc2UsIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gIGRlY2xhcmF0aW9uLm1ldGhvZHMgPSBtZXRob2RTaWduYXR1cmVzLm1hcCgoc2lnbmF0dXJlLCBpbmRleCkgPT4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKHt9KSwgaWQ6IGAke2RlY2xhcmF0aW9uLmlkfTptZXRob2Q6JHtpbmRleH1gLFxuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1ldGhvZERlY2xhcmF0aW9uXCIpLCBsb2NhdGlvbjogc2lnbmF0dXJlLmxvY2F0aW9uLCBuYW1lOiBzaWduYXR1cmUubmFtZSxcbiAgICBwYXJhbWV0ZXJzOiBzaWduYXR1cmUucGFyYW1ldGVycyxcbiAgICByZXR1cm5UeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSAqLyAoc2lnbmF0dXJlLnJldHVyblR5cGUpXG4gIH0sIHtuYW1lOiBzaWduYXR1cmUubmFtZUxvY2F0aW9ufSkpXG4gIGNvbnN0IGJhc2UgPSB7YmluZGluZ3M6IG5ldyBNYXAoKSwgY2xhc3NlcywgY3VycmVudENsYXNzOiBkZWNsYXJhdGlvbiwgZXJyb3JOYW1lcywgZXJyb3JzLCBmdW5jdGlvbnMsXG4gICAgcmVjb3JkTmFtZXM6IG5vbWluYWxOYW1lcywgcmVjb3Jkc31cblxuICBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5ib2R5ID0gY29udmVydEJsb2NrKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CbG9ja30gKi8gKGNvbnN0cnVjdG9yTm9kZS5ib2R5KSwgZmlsZW5hbWUsIHNvdXJjZSxcbiAgICB7Li4uYmFzZSwgYmluZGluZ3M6IG5ldyBNYXAoZGVjbGFyYXRpb24uY29uc3RydWN0b3IucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gW3BhcmFtZXRlci5uYW1lLCBwYXJhbWV0ZXIudHlwZV0pKSxcbiAgICAgIHJldHVyblR5cGU6IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJUeXBlUmVmZXJlbmNlXCIpLCBuYW1lOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ2b2lkXCIpfX0pXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBvcmRpbmFyeU1ldGhvZHMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgbWV0aG9kID0gZGVjbGFyYXRpb24ubWV0aG9kc1tpbmRleF1cblxuICAgIG1ldGhvZC5ib2R5ID0gY29udmVydEJsb2NrKC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5CbG9ja30gKi8gKG9yZGluYXJ5TWV0aG9kc1tpbmRleF0uYm9keSksIGZpbGVuYW1lLCBzb3VyY2UsXG4gICAgICB7Li4uYmFzZSwgYmluZGluZ3M6IG5ldyBNYXAobWV0aG9kLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyLnR5cGVdKSksIHJldHVyblR5cGU6IG1ldGhvZC5yZXR1cm5UeXBlfSlcbiAgfVxuICBjb25zdCBuYW1lTm9kZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUgOiBub2RlLm5hbWVcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhkZWNsYXJhdGlvbiwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBmaW5hbCByZWFkb25seSBwcm9tb3RlZC1wcm9wZXJ0eSBQSFAgcmVjb3JkLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNsYXNzfSBub2RlIC0gUEhQIGNsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBQcmVkZWNsYXJlZCBub21pbmFsIGlkZW50aXR5LlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gUmVjb3JkIGRlY2xhcmF0aW9ucyBieSBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gU2VtYW50aWMgcmVjb3JkLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UGhwUmVjb3JkKG5vZGUsIGRlY2xhcmF0aW9uLCByZWNvcmROYW1lcywgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBnZW5lcmljID0gKGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzPy5sZW5ndGggPz8gMCkgPiAwXG5cbiAgaWYgKG5vZGUuaXNBbm9ueW1vdXMgfHwgIW5vZGUuaXNGaW5hbCB8fCBub2RlLmlzUmVhZG9ubHkgPT0gZ2VuZXJpYyB8fCBub2RlLmlzQWJzdHJhY3QgfHwgbm9kZS5leHRlbmRzIHx8IG5vZGUuaW1wbGVtZW50cz8ubGVuZ3RoIHx8XG4gICAgbm9kZS5hdHRyR3JvdXBzLmxlbmd0aCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHJlY29yZCBjbGFzcyBtb2RpZmllcnNcIiwgbG9jYXRpb24pXG4gIGlmIChub2RlLmJvZHkubGVuZ3RoIDwgMSB8fCBub2RlLmJvZHlbMF0ua2luZCAhPSBcIm1ldGhvZFwiIHx8ICFnZW5lcmljICYmIG5vZGUuYm9keS5sZW5ndGggIT0gMSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInJlY29yZCBjbGFzcyBib2R5IG91dHNpZGUgb25lIGNvbnN0cnVjdG9yXCIsIG5vZGVMb2NhdGlvbihub2RlLmJvZHlbMV0gPz8gbm9kZS5ib2R5WzBdID8/IG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGNvbnN0cnVjdG9yID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk1ldGhvZH0gKi8gKG5vZGUuYm9keVswXSlcbiAgY29uc3QgdHlwZVBhcmFtZXRlck5hbWVzID0gbmV3IE1hcCgoZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPz8gW10pLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlcl0pKVxuICBjb25zdCBjb25zdHJ1Y3Rvck5hbWUgPSB0eXBlb2YgY29uc3RydWN0b3IubmFtZSA9PSBcInN0cmluZ1wiID8gY29uc3RydWN0b3IubmFtZSA6IGNvbnN0cnVjdG9yLm5hbWUubmFtZVxuXG4gIGlmIChjb25zdHJ1Y3Rvck5hbWUgIT0gXCJfX2NvbnN0cnVjdFwiIHx8IGNvbnN0cnVjdG9yLnZpc2liaWxpdHkgIT0gXCJwdWJsaWNcIiB8fCBjb25zdHJ1Y3Rvci5pc1N0YXRpYyB8fCBjb25zdHJ1Y3Rvci5pc0Fic3RyYWN0IHx8XG4gICAgY29uc3RydWN0b3IuaXNGaW5hbCB8fCBSZWZsZWN0LmdldChjb25zdHJ1Y3RvciwgXCJpc1JlYWRvbmx5XCIpIHx8IGNvbnN0cnVjdG9yLmJ5cmVmIHx8IGNvbnN0cnVjdG9yLnR5cGUgfHwgY29uc3RydWN0b3IubnVsbGFibGUgfHxcbiAgICBjb25zdHJ1Y3Rvci5hdHRyR3JvdXBzLmxlbmd0aCB8fCAhY29uc3RydWN0b3IuYm9keSB8fCBjb25zdHJ1Y3Rvci5ib2R5LmNoaWxkcmVuLmxlbmd0aCAhPSAwKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIHJlY29yZCBjb25zdHJ1Y3RvclwiLCBub2RlTG9jYXRpb24oY29uc3RydWN0b3IsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGRvY3VtZW50ZWQgPSBmdW5jdGlvbkRvY3VtZW50ZWRUeXBlcygvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChjb25zdHJ1Y3RvcikpLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGRlY2xhcmF0aW9uLmZpZWxkcyA9IGNvbnN0cnVjdG9yLmFyZ3VtZW50cy5tYXAoKHBhcmFtZXRlcikgPT4ge1xuICAgIGNvbnN0IGZpZWxkTG9jYXRpb24gPSBub2RlTG9jYXRpb24ocGFyYW1ldGVyLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlci5uYW1lIDogcGFyYW1ldGVyLm5hbWUubmFtZVxuICAgIGNvbnN0IGRvY3VtZW50ZWRUeXBlID0gZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmdldChuYW1lKVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShwYXJhbWV0ZXIudHlwZSlcblxuICAgIGlmIChwYXJhbWV0ZXIuZmxhZ3MgIT0gKGdlbmVyaWMgPyA0IDogMSkgfHwgcGFyYW1ldGVyLmJ5cmVmIHx8IHBhcmFtZXRlci52YXJpYWRpYyB8fCBwYXJhbWV0ZXIudmFsdWUgfHwgcGFyYW1ldGVyLnJlYWRvbmx5IHx8XG4gICAgICBwYXJhbWV0ZXIuaG9va3MubGVuZ3RoIHx8IHBhcmFtZXRlci5hdHRyR3JvdXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwicmVjb3JkIGZpZWxkIG91dHNpZGUgcHVibGljIHByb21vdGVkLXByb3BlcnR5IHByb2ZpbGVcIiwgZmllbGRMb2NhdGlvbilcbiAgICB9XG4gICAgaWYgKG5hdGl2ZVR5cGUgPT0gXCJhcnJheVwiICYmICFkb2N1bWVudGVkVHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBSZWNvcmQgZmllbGQgJyR7bmFtZX0nYCwgZmllbGRMb2NhdGlvbilcbiAgICBsZXQgdHlwZSA9IGRvY3VtZW50ZWRUeXBlXG4gICAgICA/IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZFR5cGUubG9jYXRpb24sIG93bmVyTG9jYXRpb246IGZpZWxkTG9jYXRpb24sIHJlY29yZHM6IHJlY29yZE5hbWVzLFxuICAgICAgICBzb3VyY2UsIHNvdXJjZVR5cGU6IGRvY3VtZW50ZWRUeXBlLnNvdXJjZVR5cGUsIHN1YmplY3Q6IGBSZWNvcmQgZmllbGQgJyR7bmFtZX0nYCwgdHlwZVBhcmFtZXRlcnM6IHR5cGVQYXJhbWV0ZXJOYW1lc30pXG4gICAgICA6IGNvbnZlcnRUeXBlKHBhcmFtZXRlci50eXBlLCBgUmVjb3JkIGZpZWxkICcke25hbWV9J2AsIGZpZWxkTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzKVxuXG4gICAgaWYgKGRvY3VtZW50ZWRUeXBlICYmICFwaHBEb2N1bWVudGVkTmF0aXZlVHlwZU1hdGNoZXMobmF0aXZlVHlwZSwgcGFyYW1ldGVyLm51bGxhYmxlLCB0eXBlLCByZWNvcmROYW1lcykpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImRvY3VtZW50ZWQgcmVjb3JkIGZpZWxkIHR5cGUgaW5jb21wYXRpYmxlIHdpdGggbmF0aXZlIHR5cGVcIiwgZG9jdW1lbnRlZFR5cGUubG9jYXRpb24pXG4gICAgfVxuXG4gICAgaWYgKHBhcmFtZXRlci5udWxsYWJsZSAmJiB0eXBlLmtpbmQgIT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgICAgaWYgKCFwYXJhbWV0ZXIudHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwicGhwXCIsIGBSZWNvcmQgZmllbGQgJyR7bmFtZX0nYCwgZmllbGRMb2NhdGlvbilcbiAgICAgIHR5cGUgPSBudWxsYWJsZVR5cGUodHlwZSwgcGFyYW1ldGVyLnR5cGUsIHBhcmFtZXRlci5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0gZWxzZSBpZiAoIXBhcmFtZXRlci5udWxsYWJsZSAmJiB0eXBlLmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIiAmJiB0eXBlLnZhbHVlVHlwZS5raW5kICE9IFwiVHlwZVZhcmlhYmxlUmVmZXJlbmNlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9wdGlvbmFsIGFubm90YXRpb24gd2l0aG91dCBudWxsYWJsZSBuYXRpdmUgcmVjb3JkIGZpZWxkXCIsIGRvY3VtZW50ZWRUeXBlPy5sb2NhdGlvbiA/PyBmaWVsZExvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBmaWVsZCA9IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJSZWNvcmRGaWVsZFwiKSwgbG9jYXRpb246IGZpZWxkTG9jYXRpb24sIG5hbWUsIHR5cGV9XG4gICAgY29uc3QgbmFtZU5vZGUgPSB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IHBhcmFtZXRlciA6IHBhcmFtZXRlci5uYW1lXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhmaWVsZCwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9KVxuICBjb25zdCBleHRyYURvY3VtZW50ZWQgPSBbLi4uZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLmtleXMoKV0uZmluZCgobmFtZSkgPT5cbiAgICAhY29uc3RydWN0b3IuYXJndW1lbnRzLnNvbWUoKHBhcmFtZXRlcikgPT4gKHR5cGVvZiBwYXJhbWV0ZXIubmFtZSA9PSBcInN0cmluZ1wiID8gcGFyYW1ldGVyLm5hbWUgOiBwYXJhbWV0ZXIubmFtZS5uYW1lKSA9PSBuYW1lKSlcblxuICBpZiAoZXh0cmFEb2N1bWVudGVkIHx8IGRvY3VtZW50ZWQucmV0dXJuVHlwZSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaW52YWxpZCByZWNvcmQgY29uc3RydWN0b3IgYW5ub3RhdGlvblwiLCBsb2NhdGlvbilcbiAgaWYgKGdlbmVyaWMpIHZhbGlkYXRlUGhwR2VuZXJpY1JlY29yZEdldHRlcnMobm9kZSwgZGVjbGFyYXRpb24sIHJlY29yZE5hbWVzLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBuYW1lTm9kZSA9IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUgOiBub2RlLm5hbWVcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhkZWNsYXJhdGlvbiwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIFZhbGlkYXRlcyB0aGUgZXhhY3QgYWNjZXNzb3IgaGFsZiBvZiBQSFAncyBkb2N1bWVudGVkIGdlbmVyaWMtcmVjb3JkIHByb2ZpbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuQ2xhc3N9IG5vZGUgLSBQSFAgY2xhc3MgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIENvbnZlcnRlZCByZWNvcmQuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPn0gcmVjb3JkTmFtZXMgLSBWaXNpYmxlIHJlY29yZHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlUGhwR2VuZXJpY1JlY29yZEdldHRlcnMobm9kZSwgZGVjbGFyYXRpb24sIHJlY29yZE5hbWVzLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGdldHRlcnMgPSBub2RlLmJvZHkuc2xpY2UoMSlcbiAgY29uc3QgdHlwZVBhcmFtZXRlcnMgPSBuZXcgTWFwKChkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/PyBbXSkubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyXSkpXG5cbiAgaWYgKGdldHRlcnMubGVuZ3RoICE9IGRlY2xhcmF0aW9uLmZpZWxkcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJnZW5lcmljIHJlY29yZCBnZXR0ZXIgY291bnRcIiwgbm9kZUxvY2F0aW9uKGdldHRlcnNbZGVjbGFyYXRpb24uZmllbGRzLmxlbmd0aF0gPz8gbm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgZ2V0dGVycy5mb3JFYWNoKChjYW5kaWRhdGUsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgZmllbGQgPSBkZWNsYXJhdGlvbi5maWVsZHNbaW5kZXhdXG5cbiAgICBpZiAoY2FuZGlkYXRlLmtpbmQgIT0gXCJtZXRob2RcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibm9uY2Fub25pY2FsIGdlbmVyaWMgcmVjb3JkIGdldHRlclwiLCBub2RlTG9jYXRpb24oY2FuZGlkYXRlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICBjb25zdCBnZXR0ZXIgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTWV0aG9kfSAqLyAoY2FuZGlkYXRlKVxuICAgIGNvbnN0IG5hbWUgPSB0eXBlb2YgZ2V0dGVyLm5hbWUgPT0gXCJzdHJpbmdcIiA/IGdldHRlci5uYW1lIDogZ2V0dGVyLm5hbWUubmFtZVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IGdldHRlci5ib2R5Py5jaGlsZHJlblswXVxuICAgIGNvbnN0IHJldHVybmVkID0gc3RhdGVtZW50Py5raW5kID09IFwicmV0dXJuXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuUmV0dXJufSAqLyAoc3RhdGVtZW50KS5leHByIDogdW5kZWZpbmVkXG4gICAgY29uc3QgbG9va3VwID0gcmV0dXJuZWQ/LmtpbmQgPT0gXCJwcm9wZXJ0eWxvb2t1cFwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb3BlcnR5TG9va3VwfSAqLyAocmV0dXJuZWQpIDogdW5kZWZpbmVkXG4gICAgY29uc3QgcmVjZWl2ZXIgPSBsb29rdXA/LndoYXQua2luZCA9PSBcInZhcmlhYmxlXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuVmFyaWFibGV9ICovIChsb29rdXAud2hhdCkgOiB1bmRlZmluZWRcbiAgICBjb25zdCBtZW1iZXIgPSBsb29rdXA/Lm9mZnNldC5raW5kID09IFwiaWRlbnRpZmllclwiID8gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLklkZW50aWZpZXJ9ICovIChsb29rdXAub2Zmc2V0KSA6IHVuZGVmaW5lZFxuXG4gICAgaWYgKG5hbWUgIT0gZmllbGQubmFtZSB8fCBnZXR0ZXIudmlzaWJpbGl0eSAhPSBcInB1YmxpY1wiIHx8IGdldHRlci5pc1N0YXRpYyB8fCBnZXR0ZXIuaXNBYnN0cmFjdCB8fCBnZXR0ZXIuaXNGaW5hbCB8fFxuICAgICAgUmVmbGVjdC5nZXQoZ2V0dGVyLCBcImlzUmVhZG9ubHlcIikgfHwgZ2V0dGVyLmJ5cmVmIHx8IGdldHRlci5hcmd1bWVudHMubGVuZ3RoIHx8IGdldHRlci5hdHRyR3JvdXBzLmxlbmd0aCB8fFxuICAgICAgIWdldHRlci5ib2R5IHx8IGdldHRlci5ib2R5LmNoaWxkcmVuLmxlbmd0aCAhPSAxIHx8IHJlY2VpdmVyPy5uYW1lICE9IFwidGhpc1wiIHx8IG1lbWJlcj8ubmFtZSAhPSBmaWVsZC5uYW1lKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJub25jYW5vbmljYWwgZ2VuZXJpYyByZWNvcmQgZ2V0dGVyXCIsIG5vZGVMb2NhdGlvbihnZXR0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBjb25zdCBkb2N1bWVudGVkID0gZnVuY3Rpb25Eb2N1bWVudGVkVHlwZXMoXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChnZXR0ZXIpKSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChkb2N1bWVudGVkLnBhcmFtZXRlcnMuc2l6ZSB8fCBkb2N1bWVudGVkLnR5cGVQYXJhbWV0ZXJzIHx8ICFkb2N1bWVudGVkLnJldHVyblR5cGUpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1pc3Npbmcgb3IgaW52YWxpZCBnZW5lcmljIHJlY29yZCBnZXR0ZXIgdHlwZVwiLCBub2RlTG9jYXRpb24oZ2V0dGVyLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlOiBcInBocFwiLCBsb2NhdGlvbjogZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uLFxuICAgICAgb3duZXJMb2NhdGlvbjogbm9kZUxvY2F0aW9uKGdldHRlciwgZmlsZW5hbWUsIHNvdXJjZSksIHJlY29yZHM6IHJlY29yZE5hbWVzLCBzb3VyY2UsXG4gICAgICBzb3VyY2VUeXBlOiBkb2N1bWVudGVkLnJldHVyblR5cGUuc291cmNlVHlwZSwgc3ViamVjdDogYFJlY29yZCBnZXR0ZXIgJyR7bmFtZX0nYCwgdHlwZVBhcmFtZXRlcnN9KVxuICAgIGNvbnN0IG5hdGl2ZVR5cGUgPSBwaHBUeXBlTmFtZShnZXR0ZXIudHlwZSlcblxuICAgIGlmICghcGhwRG9jdW1lbnRlZE5hdGl2ZVR5cGVNYXRjaGVzKG5hdGl2ZVR5cGUsIGdldHRlci5udWxsYWJsZSwgcmV0dXJuVHlwZSwgcmVjb3JkTmFtZXMpIHx8XG4gICAgICAhc2FtZVZhbHVlVHlwZShyZXR1cm5UeXBlLCBmaWVsZC50eXBlKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZ2VuZXJpYyByZWNvcmQgZ2V0dGVyIHR5cGUgbWlzbWF0Y2hcIiwgZG9jdW1lbnRlZC5yZXR1cm5UeXBlLmxvY2F0aW9uKVxuICAgIH1cbiAgfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZXhpc3RpbmcgUEhQIGlmL2Vsc2UgdGVybWluYWwgd2l0aCByZXN0cmljdGVkIGJyYW5jaCBwcmVmaXhlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gbm9kZSAtIFBIUCBpZiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7UGhwQ29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9IFNlbWFudGljIGJyYW5jaC5cbiAqL1xuZnVuY3Rpb24gY29udmVydElmKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS5zaG9ydEZvcm0pIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImFsdGVybmF0aXZlIGlmIHN5bnRheFwiLCBsb2NhdGlvbilcbiAgaWYgKG5vZGUuYm9keS5raW5kICE9IFwiYmxvY2tcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiaWYgd2l0aG91dCBibG9jayBjb25zZXF1ZW50XCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS50ZXN0LmtpbmQgPT0gXCJ2YXJpYWJsZVwiKSB7XG4gICAgY29uc3QgdGVzdGVkID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlZhcmlhYmxlfSAqLyAobm9kZS50ZXN0KVxuXG4gICAgaWYgKHR5cGVvZiB0ZXN0ZWQubmFtZSA9PSBcInN0cmluZ1wiICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KHRlc3RlZC5uYW1lKT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJvcHRpb25hbCB0cnV0aGluZXNzIGNvbmRpdGlvblwiLCBub2RlTG9jYXRpb24odGVzdGVkLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBjb25kaXRpb24gPSBjb252ZXJ0RXhwcmVzc2lvbihub2RlLnRlc3QsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIGNvbnN0IGNvbnNlcXVlbnRDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuICBjb25zdCBhbHRlcm5hdGVDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuICBsZXQgYWx0ZXJuYXRlXG5cbiAgaWYgKG5vZGUuYWx0ZXJuYXRlKSB7XG4gICAgaWYgKG5vZGUuYWx0ZXJuYXRlLmtpbmQgPT0gXCJibG9ja1wiKSB7XG4gICAgICBhbHRlcm5hdGUgPSBjb252ZXJ0QmxvY2soLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5hbHRlcm5hdGUpLCBmaWxlbmFtZSwgc291cmNlLCBhbHRlcm5hdGVDb250ZXh0KVxuICAgIH0gZWxzZSBpZiAobm9kZS5hbHRlcm5hdGUua2luZCA9PSBcImlmXCIpIHtcbiAgICAgIGNvbnN0IG5lc3RlZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5JZn0gKi8gKG5vZGUuYWx0ZXJuYXRlKVxuXG4gICAgICBhbHRlcm5hdGUgPSB7XG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkJsb2NrXCIpLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5lc3RlZCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIHN0YXRlbWVudHM6IFtjb252ZXJ0SWYobmVzdGVkLCBmaWxlbmFtZSwgc291cmNlLCBhbHRlcm5hdGVDb250ZXh0KV1cbiAgICAgIH1cbiAgICB9IGVsc2UgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIGBpZiBhbHRlcm5hdGUgJHtub2RlLmFsdGVybmF0ZS5raW5kfWAsIG5vZGVMb2NhdGlvbihub2RlLmFsdGVybmF0ZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICByZXR1cm4ge1xuICAgIC4uLihhbHRlcm5hdGUgPyB7YWx0ZXJuYXRlfSA6IHt9KSxcbiAgICBjb25kaXRpb24sXG4gICAgY29uc2VxdWVudDogY29udmVydEJsb2NrKG5vZGUuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSwgY29uc2VxdWVudENvbnRleHQpLFxuICAgIGtpbmQ6IFwiSWZTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgZXhhY3QgYnJhY2VkIFBIUCBgd2hpbGUgKCRjb25kaXRpb24pIHsgLi4uIH1gIHN5bnRheC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5XaGlsZX0gbm9kZSAtIFBIUCB3aGlsZSBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7UGhwQ29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuV2hpbGVTdGF0ZW1lbnR9IFNlbWFudGljIGxvb3AuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRXaGlsZShub2RlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUuc2hvcnRGb3JtKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJhbHRlcm5hdGl2ZSB3aGlsZSBzeW50YXhcIiwgbG9jYXRpb24pXG4gIGlmICghbm9kZS5ib2R5IHx8IG5vZGUuYm9keS5raW5kICE9IFwiYmxvY2tcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIndoaWxlIHdpdGhvdXQgYmxvY2sgYm9keVwiLCBub2RlLmJvZHkgPyBub2RlTG9jYXRpb24obm9kZS5ib2R5LCBmaWxlbmFtZSwgc291cmNlKSA6IGxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGJvZHlDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuXG4gIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICBib2R5OiBjb252ZXJ0QmxvY2soLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkJsb2NrfSAqLyAobm9kZS5ib2R5KSwgZmlsZW5hbWUsIHNvdXJjZSwgYm9keUNvbnRleHQpLFxuICAgIGNvbmRpdGlvbjogY29udmVydEV4cHJlc3Npb24obm9kZS50ZXN0LCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LCB1bmRlZmluZWQsIHRydWUpLFxuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIldoaWxlU3RhdGVtZW50XCIpLFxuICAgIGxvY2F0aW9uXG4gIH0sIHtrZXl3b3JkOiB0b2tlbkxvY2F0aW9uKFwid2hpbGVcIiwgbm9kZS5sb2M/LnN0YXJ0Lm9mZnNldCA/PyAwLCBub2RlLnRlc3QubG9jPy5zdGFydC5vZmZzZXQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgUEhQIGVjaG8gZW50cnkgcG9pbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuRWNob30gbm9kZSAtIFBIUCBlY2hvIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtQaHBDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QcmludFN0YXRlbWVudH0gUHJpbnQgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UHJpbnQobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLmV4cHJlc3Npb25zLmxlbmd0aCAhPSAyIHx8IG5vZGUuZXhwcmVzc2lvbnNbMV0ua2luZCAhPSBcIm5hbWVcIiB8fFxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5OYW1lfSAqLyAobm9kZS5leHByZXNzaW9uc1sxXSkubmFtZSAhPSBcIlBIUF9FT0xcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImVjaG8gd2l0aG91dCBvbmUgZXhwcmVzc2lvbiBhbmQgUEhQX0VPTFwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIHJldHVybiB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24obm9kZS5leHByZXNzaW9uc1swXSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksIGtpbmQ6IFwiUHJpbnRTdGF0ZW1lbnRcIiwgbG9jYXRpb259XG59XG5cbi8qKlxuICogUGFyc2VzIFBIUCBpbnRvIHRoZSBzaGFyZWQgc2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtvYmplY3R9IGlucHV0IC0gUGFyc2VyIGlucHV0LlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LmZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LnNvdXJjZSAtIFNvdXJjZSB0ZXh0LlxuICogQHBhcmFtIHtyZWFkb25seSBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RDYXBhYmlsaXR5RGVjbGFyYXRpb25bXX0gW2lucHV0LmNhcGFiaWxpdGllc10gLSBDb21waWxlci1hdXRob3JpemVkIGRlY2xhcmF0aW9ucy5cbiAqIEBwYXJhbSB7e2lzRW50cnk6IGJvb2xlYW4sIGZ1bmN0aW9uczogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbj4sIHJlY29yZHM6IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPiwgZXJyb3JzPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbj59fSBbaW5wdXQucHJvZ3JhbV0gLSBSZXNvbHZlZCBwcm9ncmFtIGltcG9ydHMgYW5kIGVudHJ5IHJvbGUuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNNb2R1bGV9IFNlbWFudGljIG1vZHVsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlUGhwKHtjYXBhYmlsaXRpZXMgPSBbXSwgZmlsZW5hbWUsIHNvdXJjZSwgcHJvZ3JhbTogcHJvZ3JhbUNvbnRleHR9KSB7XG4gIGNvbnN0IHByb2dyYW0gPSBwYXJzZVBocFByb2dyYW0oZmlsZW5hbWUsIHNvdXJjZSlcbiAgdmFsaWRhdGVEZWNsYXJlTm9kZXMocHJvZ3JhbS5jaGlsZHJlbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgbGV0IGJvZHkgPSB0YXNrMDM0UGhwQm9keShwcm9ncmFtLmNoaWxkcmVuLCBjYXBhYmlsaXRpZXMsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKHByb2dyYW1Db250ZXh0KSB7XG4gICAgaW5zcGVjdFBocE1vZHVsZSh7ZmlsZW5hbWUsIHNvdXJjZX0pXG4gICAgY29uc3QgbmFtZXNwYWNlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWVzcGFjZX0gKi8gKGJvZHkuZmluZCgobm9kZSkgPT4gbm9kZS5raW5kID09IFwibmFtZXNwYWNlXCIpKVxuXG4gICAgYm9keSA9IG5hbWVzcGFjZS5jaGlsZHJlbi5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCAhPSBcInVzZWdyb3VwXCIgJiYgIWlzUGhwUmVxdWlyZU9uY2Uobm9kZSkpXG4gIH1cbiAgY29uc3QgY2xhc3NOb2RlcyA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5DbGFzc1tdfSAqLyAoYm9keS5maWx0ZXIoKG5vZGUpID0+IG5vZGUua2luZCA9PSBcImNsYXNzXCIpKVxuICBjb25zdCBlcnJvck5vZGVzID0gY2xhc3NOb2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUuZXh0ZW5kcz8ua2luZCA9PSBcIm5hbWVcIiAmJlxuICAgIFtcIlJ1bnRpbWVFeGNlcHRpb25cIiwgXCJcXFxcUnVudGltZUV4Y2VwdGlvblwiXS5pbmNsdWRlcyhub2RlLmV4dGVuZHMubmFtZSkpXG4gIGNvbnN0IHJlZmVyZW5jZUNsYXNzTm9kZXMgPSBjbGFzc05vZGVzLmZpbHRlcigobm9kZSkgPT4gIWVycm9yTm9kZXMuaW5jbHVkZXMobm9kZSkgJiZcbiAgICBub2RlLmJvZHkuc29tZSgobWVtYmVyKSA9PiBtZW1iZXIua2luZCA9PSBcInByb3BlcnR5c3RhdGVtZW50XCIpKVxuICBjb25zdCByZWNvcmROb2RlcyA9IGNsYXNzTm9kZXMuZmlsdGVyKChub2RlKSA9PiAhZXJyb3JOb2Rlcy5pbmNsdWRlcyhub2RlKSAmJiAhcmVmZXJlbmNlQ2xhc3NOb2Rlcy5pbmNsdWRlcyhub2RlKSlcbiAgY29uc3QgZXJyb3JEZWNsYXJhdGlvbnMgPSBlcnJvck5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+ICh7XG4gICAgaWQ6IGBlcnJvcjoke2luZGV4fWAsXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JEZWNsYXJhdGlvblwiKSxcbiAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIG5hbWU6IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG4gIH0pKVxuICBjb25zdCByZWNvcmREZWNsYXJhdGlvbnMgPSByZWNvcmROb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgaWQgPSBgcmVjb3JkOiR7aW5kZXh9YFxuICAgIGNvbnN0IHR5cGVQYXJhbWV0ZXJzID0gY2xhc3NEb2N1bWVudGVkVHlwZVBhcmFtZXRlcnMobm9kZSwgaWQsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICByZXR1cm4ge1xuICAgICAgZmllbGRzOiBbXSxcbiAgICAgIGlkLFxuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVjb3JkRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbmFtZTogdHlwZW9mIG5vZGUubmFtZSA9PSBcInN0cmluZ1wiID8gbm9kZS5uYW1lIDogbm9kZS5uYW1lLm5hbWUsXG4gICAgICAuLi4odHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnN9IDoge30pXG4gICAgfVxuICB9KVxuICBjb25zdCBjbGFzc0RlY2xhcmF0aW9ucyA9IHJlZmVyZW5jZUNsYXNzTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gKHtcbiAgICBjb25zdHJ1Y3RvcjogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Db25zdHJ1Y3RvckRlY2xhcmF0aW9ufSAqLyAoe30pLFxuICAgIGZpZWxkczogW10sIGlkOiBgY2xhc3M6JHtpbmRleH1gLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDbGFzc0RlY2xhcmF0aW9uXCIpLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksIG1ldGhvZHM6IFtdLFxuICAgIG5hbWU6IHR5cGVvZiBub2RlLm5hbWUgPT0gXCJzdHJpbmdcIiA/IG5vZGUubmFtZSA6IG5vZGUubmFtZS5uYW1lXG4gIH0pKVxuICBjb25zdCByZWNvcmROYW1lcyA9IC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59ICovIChcbiAgICBuZXcgTWFwKHByb2dyYW1Db250ZXh0Py5yZWNvcmRzID8/IFtdKSlcbiAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBjYXBhYmlsaXRpZXMuZmxhdE1hcCgoe3Jlc291cmNlc30pID0+IHJlc291cmNlcykpIHJlY29yZE5hbWVzLnNldChyZXNvdXJjZS5uYW1lLCByZXNvdXJjZSlcbiAgY29uc3QgZXJyb3JOYW1lcyA9IG5ldyBNYXAocHJvZ3JhbUNvbnRleHQ/LmVycm9ycyA/PyBbXSlcbiAgZm9yIChjb25zdCBmYWlsdXJlIG9mIGNhcGFiaWxpdGllcy5mbGF0TWFwKCh7ZmFpbHVyZXN9KSA9PiBmYWlsdXJlcykpIHtcbiAgICBlcnJvck5hbWVzLnNldChmYWlsdXJlLm5hbWUsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGZhaWx1cmUpKSlcbiAgfVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGVycm9yRGVjbGFyYXRpb25zKSBlcnJvck5hbWVzLnNldChkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbilcbiAgY29uc3QgZXJyb3JzQnlJZCA9IG5ldyBNYXAoWy4uLmVycm9yTmFtZXMudmFsdWVzKCldLm1hcCgoZGVjbGFyYXRpb24pID0+IFsvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgZGVjbGFyYXRpb25dKSlcbiAgY29uc3QgZXJyb3JzID0gZXJyb3JOb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiBjb252ZXJ0UGhwRXJyb3Iobm9kZSwgZXJyb3JEZWNsYXJhdGlvbnNbaW5kZXhdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiByZWNvcmREZWNsYXJhdGlvbnMpIHJlY29yZE5hbWVzLnNldChkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbilcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBjbGFzc0RlY2xhcmF0aW9ucykgcmVjb3JkTmFtZXMuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uKVxuICBjb25zdCByZWNvcmRzQnlJZCA9IG5ldyBNYXAoWy4uLnJlY29yZE5hbWVzLnZhbHVlcygpXVxuICAgIC5maWx0ZXIoKGRlY2xhcmF0aW9uKSA9PiBkZWNsYXJhdGlvbi5raW5kID09IFwiUmVjb3JkRGVjbGFyYXRpb25cIilcbiAgICAubWFwKChkZWNsYXJhdGlvbikgPT4gWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbl0pKVxuICBjb25zdCBjbGFzc2VzQnlJZCA9IG5ldyBNYXAoY2xhc3NEZWNsYXJhdGlvbnMubWFwKChkZWNsYXJhdGlvbikgPT4gWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbl0pKVxuICBjb25zdCByZWNvcmRzID0gcmVjb3JkTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydFBocFJlY29yZChub2RlLCByZWNvcmREZWNsYXJhdGlvbnNbaW5kZXhdLFxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24+fSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAocmVjb3JkTmFtZXMpKSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGNvbnN0IGZ1bmN0aW9uTm9kZXMgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRnVuY3Rpb25bXX0gKi8gKGJvZHkuZmlsdGVyKChub2RlKSA9PiBub2RlLmtpbmQgPT0gXCJmdW5jdGlvblwiKSlcbiAgY29uc3Qgc2lnbmF0dXJlcyA9IGZ1bmN0aW9uTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydEZ1bmN0aW9uU2lnbmF0dXJlKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzLCBgZnVuY3Rpb246JHtpbmRleH1gKSlcbiAgY29uc3QgZnVuY3Rpb25TaWduYXR1cmVzID0gbmV3IE1hcChbLi4uY2FwYWJpbGl0eUZ1bmN0aW9uU2lnbmF0dXJlcyhjYXBhYmlsaXRpZXMsIG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpKSxcbiAgICAuLi4ocHJvZ3JhbUNvbnRleHQ/LmZ1bmN0aW9ucyA/PyBbXSldLm1hcCgoW2xvY2FsTmFtZSwgZGVjbGFyYXRpb25dKSA9PiBbbG9jYWxOYW1lLCB7XG4gICAgbG9jYXRpb246IGRlY2xhcmF0aW9uLmxvY2F0aW9uLFxuICAgIG5hbWU6IGxvY2FsTmFtZSxcbiAgICBuYW1lTG9jYXRpb246IGRlY2xhcmF0aW9uLmxvY2F0aW9uLFxuICAgIHBhcmFtZXRlcnM6IGRlY2xhcmF0aW9uLnBhcmFtZXRlcnMsXG4gICAgcmV0dXJuVHlwZTogZGVjbGFyYXRpb24ucmV0dXJuVHlwZSxcbiAgICAuLi4oZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IGRlY2xhcmF0aW9uLnR5cGVQYXJhbWV0ZXJzfSA6IHt9KVxuICB9XSkpXG4gIGZvciAoY29uc3Qgc2lnbmF0dXJlIG9mIHNpZ25hdHVyZXMpIGZ1bmN0aW9uU2lnbmF0dXJlcy5zZXQoc2lnbmF0dXJlLm5hbWUsIHNpZ25hdHVyZSlcbiAgY29uc3QgY2xhc3NlcyA9IHJlZmVyZW5jZUNsYXNzTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydFBocFJlZmVyZW5jZUNsYXNzKG5vZGUsIGNsYXNzRGVjbGFyYXRpb25zW2luZGV4XSxcbiAgICByZWNvcmROYW1lcywgcmVjb3Jkc0J5SWQsIGNsYXNzZXNCeUlkLCBmdW5jdGlvblNpZ25hdHVyZXMsIGVycm9yTmFtZXMsIGVycm9yc0J5SWQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCBmdW5jdGlvbnMgPSBmdW5jdGlvbk5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+XG4gICAgY29udmVydEZ1bmN0aW9uKG5vZGUsIHNpZ25hdHVyZXNbaW5kZXhdLCBmdW5jdGlvblNpZ25hdHVyZXMsIHJlY29yZE5hbWVzLCByZWNvcmRzQnlJZCwgY2xhc3Nlc0J5SWQsIGVycm9yTmFtZXMsIGVycm9yc0J5SWQsXG4gICAgICBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgZXhlY3V0YWJsZU5vZGVzID0gYm9keS5maWx0ZXIoKG5vZGUpID0+ICFbXCJjbGFzc1wiLCBcImZ1bmN0aW9uXCIsIFwiZGVjbGFyZVwiLCBcIm5vb3BcIl0uaW5jbHVkZXMobm9kZS5raW5kKSlcbiAgY29uc3QgbG9jYXRpb24gPSBtb2R1bGVMb2NhdGlvbihmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChwcm9ncmFtQ29udGV4dCAmJiAhcHJvZ3JhbUNvbnRleHQuaXNFbnRyeSAmJiBleGVjdXRhYmxlTm9kZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcInRvcC1sZXZlbCBzaWRlIGVmZmVjdCBvdXRzaWRlIHRoZSBzZWxlY3RlZCBlbnRyeSBtb2R1bGVcIiwgbm9kZUxvY2F0aW9uKGV4ZWN1dGFibGVOb2Rlc1swXSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZmlyc3QgPSBleGVjdXRhYmxlTm9kZXNbMF1cbiAgY29uc3QgbGFzdCA9IGV4ZWN1dGFibGVOb2Rlcy5hdCgtMSkgPz8gZmlyc3RcbiAgY29uc3QgZW50cnlMb2NhdGlvbiA9IGZpcnN0XG4gICAgPyBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIGZpcnN0LmxvYz8uc3RhcnQub2Zmc2V0ID8/IDAsIGxhc3Q/LmxvYz8uZW5kLm9mZnNldCA/PyBzb3VyY2UubGVuZ3RoKVxuICAgIDogbG9jYXRpb25cbiAgY29uc3QgZW50cnlDb250ZXh0ID0ge1xuICAgIGJpbmRpbmdzOiBuZXcgTWFwKCksXG4gICAgY2xhc3NlczogY2xhc3Nlc0J5SWQsXG4gICAgZXJyb3JOYW1lcyxcbiAgICBlcnJvcnM6IGVycm9yc0J5SWQsXG4gICAgZnVuY3Rpb25zOiBmdW5jdGlvblNpZ25hdHVyZXMsXG4gICAgb3JkZXJlZE1hcERlY2xhcmF0aW9uczogb3JkZXJlZE1hcERlY2xhcmF0aW9uc0ZvclBocChleGVjdXRhYmxlTm9kZXMpLFxuICAgIHJlY29yZE5hbWVzLFxuICAgIHJlY29yZHM6IHJlY29yZHNCeUlkLFxuICAgIHJldHVyblR5cGU6IHVuZGVmaW5lZFxuICB9XG4gIGNvbnN0IGVudHJ5QmxvY2sgPSB7XG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksXG4gICAgbG9jYXRpb246IGVudHJ5TG9jYXRpb24sXG4gICAgc3RhdGVtZW50czogZXhlY3V0YWJsZU5vZGVzLm1hcCgobm9kZSkgPT4gY29udmVydFN0YXRlbWVudChub2RlLCBmaWxlbmFtZSwgc291cmNlLCBlbnRyeUNvbnRleHQpKVxuICB9XG5cbiAgaWYgKCFwcm9ncmFtQ29udGV4dCAmJiBmdW5jdGlvbnMubGVuZ3RoID09IDAgJiYgY2FwYWJpbGl0aWVzLmxlbmd0aCA9PSAwICYmICFibG9ja1JlZmVyZW5jZXNQcm90ZWN0ZWRFbnRyeShlbnRyeUJsb2NrKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm1vZHVsZSB3aXRob3V0IGEgZnVuY3Rpb25cIiwgbG9jYXRpb24pXG4gIH1cbiAgcmV0dXJuIHtcbiAgICBlbnRyeVBvaW50OiB7XG4gICAgICBib2R5OiBlbnRyeUJsb2NrLFxuICAgICAga2luZDogXCJFbnRyeVBvaW50XCIsXG4gICAgICBsb2NhdGlvbjogZW50cnlMb2NhdGlvblxuICAgIH0sXG4gICAgZnVuY3Rpb25zLFxuICAgIGtpbmQ6IFwiTW9kdWxlXCIsXG4gICAgbG9jYXRpb24sXG4gICAgLi4uKGVycm9ycy5sZW5ndGggPiAwID8ge2Vycm9yc30gOiB7fSksXG4gICAgLi4uKGNsYXNzZXMubGVuZ3RoID4gMCA/IHtjbGFzc2VzfSA6IHt9KSxcbiAgICAuLi4ocmVjb3Jkcy5sZW5ndGggPiAwID8ge3JlY29yZHN9IDoge30pXG4gIH1cbn1cblxuLyoqXG4gKiBSZW1vdmVzIGV4YWN0IHByb3RlY3RlZCBQSFAgcHJvYmUgc3VwcG9ydCBiZWZvcmUgcG9ydGFibGUgY29udmVyc2lvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdGF0ZW1lbnRbXX0gYm9keSAtIFBhcnNlZCB0b3AtbGV2ZWwgc3RhdGVtZW50cy5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0Q2FwYWJpbGl0eURlY2xhcmF0aW9uW119IGNhcGFiaWxpdGllcyAtIEF1dGhvcml6ZWQgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlN0YXRlbWVudFtdfSBQb3J0YWJsZSBzdGF0ZW1lbnRzLlxuICovXG5mdW5jdGlvbiB0YXNrMDM0UGhwQm9keShib2R5LCBjYXBhYmlsaXRpZXMsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKCFpc1Rhc2swMzRSZXNvdXJjZVByb2JlKGNhcGFiaWxpdGllcykpIHJldHVybiBib2R5XG4gIGNvbnN0IHN0YXJ0ID0gYm9keS5maW5kSW5kZXgoKG5vZGUpID0+IG5vZGUubGVhZGluZ0NvbW1lbnRzPy5zb21lKCh7dmFsdWV9KSA9PiB2YWx1ZSA9PSBcIi8qIHNlbWFudGlmb2xkLXRhc2swMzQtc3VwcG9ydCAqL1wiKSlcblxuICBpZiAoc3RhcnQgPCAwKSByZXR1cm4gYm9keVxuICBpZiAoIWhhc0V4YWN0RWZmZWN0U3VwcG9ydChzb3VyY2UsIFwicGhwXCIpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFsZm9ybWVkIHByb3RlY3RlZCBUYXNrIDAzNCBzdXBwb3J0XCIsIG5vZGVMb2NhdGlvbihib2R5W3N0YXJ0XSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZXhwZWN0ZWQgPSBbXG4gICAgW1wiY2xhc3NcIiwgXCJQcm9iZU9wZXJhdGlvbkZhaWx1cmVcIl0sIFtcImNsYXNzXCIsIFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiXSwgW1wiY2xhc3NcIiwgXCJQcm9iZVJlYWRGYWlsdXJlXCJdLFxuICAgIFtcImNsYXNzXCIsIFwiUHJvYmVDbG9zZUZhaWx1cmVcIl0sIFtcImNsYXNzXCIsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiXSwgW1wiY2xhc3NcIiwgXCJQcm9iZVJlc291cmNlXCJdLFxuICAgIFtcImV4cHJlc3Npb25zdGF0ZW1lbnRcIiwgdW5kZWZpbmVkXSwgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZUVmZmVjdFwiXSwgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZUFjcXVpcmVcIl0sXG4gICAgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZVJlYWRcIl0sIFtcImZ1bmN0aW9uXCIsIFwicHJvYmVDbG9zZVwiXSwgW1wiZnVuY3Rpb25cIiwgXCJwcm9iZVRyYWNlXCJdXG4gIF1cbiAgY29uc3QgbWF0Y2hlcyA9IGV4cGVjdGVkLmV2ZXJ5KChba2luZCwgbmFtZV0sIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgbm9kZSA9IGJvZHlbc3RhcnQgKyBpbmRleF1cbiAgICBjb25zdCByYXdOYW1lID0gbm9kZSA/IFJlZmxlY3QuZ2V0KG5vZGUsIFwibmFtZVwiKSA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IGFjdHVhbE5hbWUgPSB0eXBlb2YgcmF3TmFtZSA9PSBcInN0cmluZ1wiID8gcmF3TmFtZSA6IHJhd05hbWUgJiYgdHlwZW9mIHJhd05hbWUgPT0gXCJvYmplY3RcIiA/IFJlZmxlY3QuZ2V0KHJhd05hbWUsIFwibmFtZVwiKSA6IHVuZGVmaW5lZFxuICAgIHJldHVybiBub2RlPy5raW5kID09IGtpbmQgJiYgYWN0dWFsTmFtZSA9PSBuYW1lXG4gIH0pXG4gIGNvbnN0IG5leHQgPSBib2R5W3N0YXJ0ICsgZXhwZWN0ZWQubGVuZ3RoXVxuXG4gIGlmICghbWF0Y2hlcyB8fCBuZXh0ICYmICFuZXh0LmxlYWRpbmdDb21tZW50cz8uc29tZSgoe3ZhbHVlfSkgPT4gdmFsdWUgPT0gXCIvKiBzZW1hbnRpZm9sZC10YXNrMDM0LXN1cHBvcnQtZW5kICovXCIpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwibWFsZm9ybWVkIHByb3RlY3RlZCBUYXNrIDAzNCBzdXBwb3J0XCIsIG5vZGVMb2NhdGlvbihib2R5W3N0YXJ0XSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgcmV0dXJuIFsuLi5ib2R5LnNsaWNlKDAsIHN0YXJ0KSwgLi4uYm9keS5zbGljZShzdGFydCArIGV4cGVjdGVkLmxlbmd0aCldXG59XG5cbi8qKlxuICogUmVhZHMgdGhlIGNhbm9uaWNhbCBwYXJzZXItb3duZWQgUEhQIG5hbWVzcGFjZSwgdXNlIGJpbmRpbmdzLCBhbmQgbGl0ZXJhbCByZXF1aXJlX29uY2UgZWRnZXMuXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBQYXJzZXIgaW5wdXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuc291cmNlIC0gU291cmNlIHRleHQuXG4gKiBAcmV0dXJucyB7e2JpbmRpbmdzOiB7aW1wb3J0ZWROYW1lOiBzdHJpbmcsIGxvY2FsTmFtZTogc3RyaW5nLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIG5hdGl2ZU5hbWU6IHN0cmluZywgc3ltYm9sS2luZDogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNEZWNsYXJhdGlvbktpbmQsIHR5cGVPbmx5OiBmYWxzZX1bXSwgaW1wb3J0czoge2ltcG9ydGVkTmFtZTogc3RyaW5nLCBsb2NhbE5hbWU6IHN0cmluZywgbG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBuYW1lc3BhY2U6IHRydWUsIHBhdGhMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNwZWNpZmllcjogc3RyaW5nLCB0eXBlT25seTogZmFsc2V9W10sIGV4cG9ydHM6IHtleHBvcnRlZE5hbWU6IHN0cmluZywgbG9jYWxOYW1lOiBzdHJpbmcsIGxvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgdHlwZU9ubHk6IGZhbHNlfVtdLCBuYXRpdmVOYW1lOiBzdHJpbmd9fSBQYXJzZXItb3duZWQgUEhQIG1vZHVsZSBoZWFkZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpbnNwZWN0UGhwTW9kdWxlKHtmaWxlbmFtZSwgc291cmNlfSkge1xuICBjb25zdCBwcm9ncmFtID0gcGFyc2VQaHBQcm9ncmFtKGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgdmFsaWRhdGVEZWNsYXJlTm9kZXMocHJvZ3JhbS5jaGlsZHJlbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbmFtZXNwYWNlcyA9IHByb2dyYW0uY2hpbGRyZW4uZmlsdGVyKChub2RlKSA9PiBub2RlLmtpbmQgPT0gXCJuYW1lc3BhY2VcIilcbiAgY29uc3QgaW52YWxpZE91dGVyID0gcHJvZ3JhbS5jaGlsZHJlbi5maW5kKChub2RlKSA9PiAhW1wiZGVjbGFyZVwiLCBcIm5hbWVzcGFjZVwiLCBcIm5vb3BcIl0uaW5jbHVkZXMobm9kZS5raW5kKSlcbiAgY29uc3QgbmFtZXNwYWNlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5hbWVzcGFjZSB8IHVuZGVmaW5lZH0gKi8gKG5hbWVzcGFjZXNbMF0pXG5cbiAgaWYgKCFuYW1lc3BhY2UgfHwgbmFtZXNwYWNlcy5sZW5ndGggIT0gMSB8fCBuYW1lc3BhY2Uud2l0aEJyYWNrZXRzIHx8IHR5cGVvZiBuYW1lc3BhY2UubmFtZSAhPSBcInN0cmluZ1wiIHx8IGludmFsaWRPdXRlcikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcIm9uZSBjYW5vbmljYWwgdW5icmFja2V0ZWQgbmFtZXNwYWNlXCIsXG4gICAgICBub2RlTG9jYXRpb24oaW52YWxpZE91dGVyID8/IG5hbWVzcGFjZXNbMV0gPz8gbmFtZXNwYWNlID8/IHByb2dyYW0sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGJpbmRpbmdzID0gW11cblxuICBmb3IgKGNvbnN0IG5vZGUgb2YgbmFtZXNwYWNlLmNoaWxkcmVuLmZpbHRlcigoY2hpbGQpID0+IGNoaWxkLmtpbmQgPT0gXCJ1c2Vncm91cFwiKSkge1xuICAgIGNvbnN0IGdyb3VwID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlVzZUdyb3VwfSAqLyAobm9kZSlcblxuICAgIGlmIChncm91cC5uYW1lICE9PSBudWxsIHx8ICFbbnVsbCwgXCJmdW5jdGlvblwiXS5pbmNsdWRlcyhncm91cC50eXBlKSB8fCBncm91cC5pdGVtcy5sZW5ndGggPT0gMCkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwiZ3JvdXBlZCwgY29uc3RhbnQsIG9yIGVtcHR5IHVzZSBkZWNsYXJhdGlvblwiLCBub2RlTG9jYXRpb24oZ3JvdXAsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgZ3JvdXAuaXRlbXMpIHtcbiAgICAgIGlmIChpdGVtLnR5cGUgIT09IG51bGwgfHwgdHlwZW9mIGl0ZW0ubmFtZSAhPSBcInN0cmluZ1wiIHx8ICFpdGVtLm5hbWUuaW5jbHVkZXMoXCJcXFxcXCIpKSB7XG4gICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImdyb3VwZWQgb3IgdW5xdWFsaWZpZWQgdXNlIGl0ZW1cIiwgbm9kZUxvY2F0aW9uKGl0ZW0sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgfVxuICAgICAgY29uc3QgaW1wb3J0ZWROYW1lID0gaXRlbS5uYW1lLnNwbGl0KFwiXFxcXFwiKS5hdCgtMSlcbiAgICAgIGNvbnN0IGFsaWFzID0gaXRlbS5hbGlhc1xuXG4gICAgICBpZiAoIWltcG9ydGVkTmFtZSB8fCBhbGlhcyAmJiBhbGlhcy5raW5kICE9IFwiaWRlbnRpZmllclwiKSB7XG4gICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImludmFsaWQgdXNlIGFsaWFzXCIsIG5vZGVMb2NhdGlvbihpdGVtLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIH1cbiAgICAgIGJpbmRpbmdzLnB1c2goe1xuICAgICAgICBpbXBvcnRlZE5hbWUsXG4gICAgICAgIGxvY2FsTmFtZTogYWxpYXMgPyBhbGlhcy5uYW1lIDogaW1wb3J0ZWROYW1lLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKGl0ZW0sIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICBuYXRpdmVOYW1lOiBpdGVtLm5hbWUsXG4gICAgICAgIHN5bWJvbEtpbmQ6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNEZWNsYXJhdGlvbktpbmR9ICovIChncm91cC50eXBlID09IFwiZnVuY3Rpb25cIiA/IFwiZnVuY3Rpb25cIiA6IFwicmVjb3JkXCIpLFxuICAgICAgICB0eXBlT25seTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKGZhbHNlKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbiAgY29uc3QgaW1wb3J0cyA9IG5hbWVzcGFjZS5jaGlsZHJlbi5maWx0ZXIoaXNQaHBJbmNsdWRlU3RhdGVtZW50KS5tYXAoKG5vZGUpID0+IHtcbiAgICBpZiAoIWlzUGhwUmVxdWlyZU9uY2Uobm9kZSkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImluY2x1ZGUvcmVxdWlyZSBvdXRzaWRlIGxpdGVyYWwgcmVxdWlyZV9vbmNlIF9fRElSX18gcHJvZmlsZVwiLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGNvbnN0IHN0YXRlbWVudCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FeHByZXNzaW9uU3RhdGVtZW50fSAqLyAobm9kZSlcbiAgICBjb25zdCBpbmNsdWRlID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkluY2x1ZGV9ICovIChzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICBjb25zdCB0YXJnZXQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQmlufSAqLyAoaW5jbHVkZS50YXJnZXQpXG4gICAgY29uc3QgcGF0aCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5TdHJpbmd9ICovICh0YXJnZXQucmlnaHQpXG5cbiAgICBpZiAoIXBhdGgudmFsdWUuc3RhcnRzV2l0aChcIi9cIikgfHwgcGF0aC52YWx1ZS5pbmNsdWRlcyhcIlxcMFwiKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicGhwXCIsIFwidW5zYWZlIHJlcXVpcmVfb25jZSBwYXRoXCIsIG5vZGVMb2NhdGlvbihwYXRoLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW1wb3J0ZWROYW1lOiBcIipcIixcbiAgICAgIGxvY2FsTmFtZTogXCJcIixcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBuYW1lc3BhY2U6IC8qKiBAdHlwZSB7Y29uc3R9ICovICh0cnVlKSxcbiAgICAgIHBhdGhMb2NhdGlvbjogbm9kZUxvY2F0aW9uKHBhdGgsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgc3BlY2lmaWVyOiBgLiR7cGF0aC52YWx1ZX1gLFxuICAgICAgdHlwZU9ubHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSlcbiAgICB9XG4gIH0pXG4gIGNvbnN0IGV4cG9ydHMgPSBuYW1lc3BhY2UuY2hpbGRyZW4uZmxhdE1hcCgobm9kZSkgPT4ge1xuICAgIGlmIChub2RlLmtpbmQgIT0gXCJjbGFzc1wiICYmIG5vZGUua2luZCAhPSBcImZ1bmN0aW9uXCIpIHJldHVybiBbXVxuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLkNsYXNzIHwgaW1wb3J0KFwicGhwLXBhcnNlclwiKS5GdW5jdGlvbn0gKi8gKG5vZGUpXG4gICAgY29uc3QgbmFtZSA9IHR5cGVvZiBkZWNsYXJhdGlvbi5uYW1lID09IFwic3RyaW5nXCIgPyBkZWNsYXJhdGlvbi5uYW1lIDogZGVjbGFyYXRpb24ubmFtZS5uYW1lXG5cbiAgICByZXR1cm4gW3tleHBvcnRlZE5hbWU6IG5hbWUsIGxvY2FsTmFtZTogbmFtZSwgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSwgdHlwZU9ubHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSl9XVxuICB9KVxuXG4gIHJldHVybiB7YmluZGluZ3MsIGV4cG9ydHMsIGltcG9ydHMsIG5hdGl2ZU5hbWU6IG5hbWVzcGFjZS5uYW1lfVxufVxuXG4vKipcbiAqIFJlcG9ydHMgd2hldGhlciBhIFBIUCBzdGF0ZW1lbnQgaXMgYW55IGluY2x1ZGUvcmVxdWlyZSBleHByZXNzaW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLk5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgc3RhdGVtZW50LlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIG5vZGUgaXMgYW4gaW5jbHVkZSBleHByZXNzaW9uIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gaXNQaHBJbmNsdWRlU3RhdGVtZW50KG5vZGUpIHtcbiAgcmV0dXJuIG5vZGUua2luZCA9PSBcImV4cHJlc3Npb25zdGF0ZW1lbnRcIiAmJlxuICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5FeHByZXNzaW9uU3RhdGVtZW50fSAqLyAobm9kZSkuZXhwcmVzc2lvbi5raW5kID09IFwiaW5jbHVkZVwiXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIGEgUEhQIHN0YXRlbWVudCBpcyB0aGUgY2Fub25pY2FsIGxpdGVyYWwgcHJvamVjdCBsb2FkIGVkZ2UuXG4gKiBAcGFyYW0ge2ltcG9ydChcInBocC1wYXJzZXJcIikuTm9kZX0gbm9kZSAtIENhbmRpZGF0ZSBzdGF0ZW1lbnQuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBpcyBhIHN1cHBvcnRlZCByZXF1aXJlLW9uY2Ugc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBpc1BocFJlcXVpcmVPbmNlKG5vZGUpIHtcbiAgaWYgKCFpc1BocEluY2x1ZGVTdGF0ZW1lbnQobm9kZSkpIHJldHVybiBmYWxzZVxuICBjb25zdCBzdGF0ZW1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuRXhwcmVzc2lvblN0YXRlbWVudH0gKi8gKG5vZGUpXG4gIGNvbnN0IGluY2x1ZGUgPSAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuSW5jbHVkZX0gKi8gKHN0YXRlbWVudC5leHByZXNzaW9uKVxuICBjb25zdCB0YXJnZXQgPSBpbmNsdWRlLnRhcmdldC5raW5kID09IFwiYmluXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuQmlufSAqLyAoaW5jbHVkZS50YXJnZXQpIDogdW5kZWZpbmVkXG4gIGNvbnN0IGxlZnQgPSB0YXJnZXQ/LmxlZnQua2luZCA9PSBcIm1hZ2ljXCIgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTWFnaWN9ICovICh0YXJnZXQubGVmdCkgOiB1bmRlZmluZWRcblxuICByZXR1cm4gaW5jbHVkZS5vbmNlICYmIGluY2x1ZGUucmVxdWlyZSAmJiB0YXJnZXQ/LnR5cGUgPT0gXCIuXCIgJiZcbiAgICBsZWZ0Py52YWx1ZSA9PSBcIl9fRElSX19cIiAmJiB0YXJnZXQucmlnaHQua2luZCA9PSBcInN0cmluZ1wiXG59XG5cbi8qKlxuICogQWNjZXB0cyBvbmx5IGFuIG9wdGlvbmFsIHNpbmdsZSBgZGVjbGFyZShzdHJpY3RfdHlwZXM9MSlgIGRpcmVjdGl2ZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5Ob2RlW119IG5vZGVzIC0gVG9wLWxldmVsIFBIUCBub2Rlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gdmFsaWRhdGVEZWNsYXJlTm9kZXMobm9kZXMsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgZGVjbGFyYXRpb25zID0gbm9kZXMuZmlsdGVyKChub2RlKSA9PiBub2RlLmtpbmQgPT0gXCJkZWNsYXJlXCIpXG5cbiAgaWYgKGRlY2xhcmF0aW9ucy5sZW5ndGggPiAxKSB7XG4gICAgdW5zdXBwb3J0ZWRTeW50YXgoXCJwaHBcIiwgXCJtdWx0aXBsZSBkZWNsYXJlIGRpcmVjdGl2ZXNcIiwgbm9kZUxvY2F0aW9uKGRlY2xhcmF0aW9uc1sxXSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uTm9kZSBvZiBkZWNsYXJhdGlvbnMpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwicGhwLXBhcnNlclwiKS5EZWNsYXJlfSAqLyAoZGVjbGFyYXRpb25Ob2RlKVxuICAgIGNvbnN0IGRpcmVjdGl2ZSA9IGRlY2xhcmF0aW9uLmRpcmVjdGl2ZXNbMF1cbiAgICBjb25zdCBrZXkgPSBkaXJlY3RpdmU/LmtleVxuICAgIGNvbnN0IHZhbHVlID0gZGlyZWN0aXZlPy52YWx1ZVxuICAgIGNvbnN0IG51bWVyaWNWYWx1ZSA9IHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSBcIm9iamVjdFwiICYmIHZhbHVlLmtpbmQgPT0gXCJudW1iZXJcIlxuICAgICAgPyAvKiogQHR5cGUge2ltcG9ydChcInBocC1wYXJzZXJcIikuTnVtYmVyfSAqLyAodmFsdWUpXG4gICAgICA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IHZhbHVlSXNPbmUgPSBudW1lcmljVmFsdWU/LmxvYyAmJiBzb3VyY2Uuc2xpY2UobnVtZXJpY1ZhbHVlLmxvYy5zdGFydC5vZmZzZXQsIG51bWVyaWNWYWx1ZS5sb2MuZW5kLm9mZnNldCkgPT0gXCIxXCJcbiAgICBjb25zdCB2YWxpZCA9IGRlY2xhcmF0aW9uLm1vZGUgPT0gXCJub25lXCIgJiYgZGVjbGFyYXRpb24uY2hpbGRyZW4ubGVuZ3RoID09IDAgJiYgZGVjbGFyYXRpb24uZGlyZWN0aXZlcy5sZW5ndGggPT0gMSAmJlxuICAgICAga2V5LmtpbmQgPT0gXCJpZGVudGlmaWVyXCIgJiYga2V5Lm5hbWUgPT0gXCJzdHJpY3RfdHlwZXNcIiAmJiB2YWx1ZUlzT25lXG5cbiAgICBpZiAoIXZhbGlkKSB1bnN1cHBvcnRlZFN5bnRheChcInBocFwiLCBcImRlY2xhcmUgb3RoZXIgdGhhbiBzdHJpY3RfdHlwZXM9MVwiLCBub2RlTG9jYXRpb24oZGVjbGFyYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG59XG5cbi8qKlxuICogSW52b2tlcyBwaHAtcGFyc2VyIGFuZCBub3JtYWxpemVzIHN5bnRheCBmYWlsdXJlcy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBTb3VyY2UgdGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCJwaHAtcGFyc2VyXCIpLlByb2dyYW19IFBIUCBwcm9ncmFtLlxuICovXG5mdW5jdGlvbiBwYXJzZVBocFByb2dyYW0oZmlsZW5hbWUsIHNvdXJjZSkge1xuICB0cnkge1xuICAgIHJldHVybiBwYXJzZXIucGFyc2VDb2RlKHNvdXJjZSwgZmlsZW5hbWUpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHBhcnNlRmFpbHVyZShcInBocFwiLCBlcnJvciwgcGhwUGFyc2VyRmFpbHVyZUxvY2F0aW9uKGVycm9yLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxufVxuXG4vKipcbiAqIE5vcm1hbGl6ZXMgcGhwLXBhcnNlcidzIG9uZS1iYXNlZCBsaW5lIGFuZCB6ZXJvLWJhc2VkIGNvbHVtbiB3aGVuIHByZXNlbnQuXG4gKiBBIG1vZHVsZSByYW5nZSByZW1haW5zIHRoZSBkZXRlcm1pbmlzdGljIGZhbGxiYWNrIGZvciBvcGFxdWUgcGFyc2VyIGVycm9ycy5cbiAqIEBwYXJhbSB7dW5rbm93bn0gZXJyb3IgLSBOYXRpdmUgcGFyc2VyIGVycm9yLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gUmVxdWVzdGVkIHNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IEZhaWx1cmUgcmFuZ2UuXG4gKi9cbmZ1bmN0aW9uIHBocFBhcnNlckZhaWx1cmVMb2NhdGlvbihlcnJvciwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIWVycm9yIHx8IHR5cGVvZiBlcnJvciAhPSBcIm9iamVjdFwiKSByZXR1cm4gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbGluZSA9IFJlZmxlY3QuZ2V0KGVycm9yLCBcImxpbmVOdW1iZXJcIilcbiAgY29uc3QgY29sdW1uID0gUmVmbGVjdC5nZXQoZXJyb3IsIFwiY29sdW1uTnVtYmVyXCIpXG5cbiAgaWYgKHR5cGVvZiBsaW5lICE9IFwibnVtYmVyXCIgfHwgIU51bWJlci5pc1NhZmVJbnRlZ2VyKGxpbmUpIHx8IGxpbmUgPCAxIHx8XG4gICAgdHlwZW9mIGNvbHVtbiAhPSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcihjb2x1bW4pIHx8IGNvbHVtbiA8IDApIHtcbiAgICByZXR1cm4gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgfVxuICBsZXQgbGluZVN0YXJ0ID0gMFxuXG4gIGZvciAobGV0IGN1cnJlbnQgPSAxOyBjdXJyZW50IDwgbGluZTsgY3VycmVudCsrKSB7XG4gICAgY29uc3QgbmV3bGluZSA9IHNvdXJjZS5pbmRleE9mKFwiXFxuXCIsIGxpbmVTdGFydClcblxuICAgIGlmIChuZXdsaW5lIDwgMCkgcmV0dXJuIG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgbGluZVN0YXJ0ID0gbmV3bGluZSArIDFcbiAgfVxuICBjb25zdCBsaW5lRW5kID0gc291cmNlLmluZGV4T2YoXCJcXG5cIiwgbGluZVN0YXJ0KVxuICBjb25zdCBib3VuZGVkRW5kID0gbGluZUVuZCA8IDAgPyBzb3VyY2UubGVuZ3RoIDogbGluZUVuZFxuICBjb25zdCBvZmZzZXQgPSBNYXRoLm1pbihsaW5lU3RhcnQgKyBjb2x1bW4sIGJvdW5kZWRFbmQpXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgb2Zmc2V0LCBNYXRoLm1pbihvZmZzZXQgKyAxLCBzb3VyY2UubGVuZ3RoKSlcbn1cbiJdfQ==
|