semantifold 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -15
- package/build/index.d.ts +48 -2
- package/build/index.d.ts.map +1 -1
- package/build/index.js +57 -8
- package/build/src/artifact-path.d.ts +23 -1
- package/build/src/artifact-path.d.ts.map +1 -1
- package/build/src/artifact-path.js +45 -3
- package/build/src/artifacts.d.ts.map +1 -1
- package/build/src/artifacts.js +66 -1
- package/build/src/backends/c-validation.d.ts.map +1 -1
- package/build/src/backends/c-validation.js +7 -3
- package/build/src/backends/cpp-validation.d.ts.map +1 -1
- package/build/src/backends/cpp-validation.js +7 -3
- package/build/src/backends/csharp.js +7 -1
- package/build/src/backends/dart-runtime.d.ts +2 -0
- package/build/src/backends/dart-runtime.d.ts.map +1 -0
- package/build/src/backends/dart-runtime.js +41 -0
- package/build/src/backends/dart.d.ts +20 -0
- package/build/src/backends/dart.d.ts.map +1 -0
- package/build/src/backends/dart.js +321 -0
- package/build/src/backends/effects.d.ts +60 -0
- package/build/src/backends/effects.d.ts.map +1 -0
- package/build/src/backends/effects.js +746 -0
- package/build/src/backends/go.js +18 -4
- package/build/src/backends/identifiers.d.ts +36 -4
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +154 -10
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -4
- package/build/src/backends/ios.d.ts +68 -0
- package/build/src/backends/ios.d.ts.map +1 -0
- package/build/src/backends/ios.js +1503 -0
- package/build/src/backends/java.d.ts.map +1 -1
- package/build/src/backends/java.js +429 -36
- package/build/src/backends/javascript.d.ts +6 -0
- package/build/src/backends/javascript.d.ts.map +1 -1
- package/build/src/backends/javascript.js +380 -24
- package/build/src/backends/kotlin-runtime.d.ts +3 -0
- package/build/src/backends/kotlin-runtime.d.ts.map +1 -0
- package/build/src/backends/kotlin-runtime.js +29 -0
- package/build/src/backends/kotlin.d.ts +23 -0
- package/build/src/backends/kotlin.d.ts.map +1 -0
- package/build/src/backends/kotlin.js +136 -0
- package/build/src/backends/native-validation.d.ts +2 -2
- package/build/src/backends/native-validation.d.ts.map +1 -1
- package/build/src/backends/native-validation.js +2 -2
- package/build/src/backends/ordered-expressions.d.ts.map +1 -1
- package/build/src/backends/ordered-expressions.js +39 -7
- package/build/src/backends/php-stdlib-support.d.ts +19 -0
- package/build/src/backends/php-stdlib-support.d.ts.map +1 -0
- package/build/src/backends/php-stdlib-support.js +227 -0
- package/build/src/backends/php.d.ts.map +1 -1
- package/build/src/backends/php.js +448 -33
- package/build/src/backends/program.d.ts +81 -0
- package/build/src/backends/program.d.ts.map +1 -0
- package/build/src/backends/program.js +1308 -0
- package/build/src/backends/python.js +7 -1
- package/build/src/backends/ruby.d.ts.map +1 -1
- package/build/src/backends/ruby.js +310 -24
- package/build/src/backends/rust-runtime.d.ts +7 -0
- package/build/src/backends/rust-runtime.d.ts.map +1 -0
- package/build/src/backends/rust-runtime.js +32 -0
- package/build/src/backends/rust-validation.d.ts +9 -0
- package/build/src/backends/rust-validation.d.ts.map +1 -0
- package/build/src/backends/rust-validation.js +78 -0
- package/build/src/backends/rust.d.ts +24 -0
- package/build/src/backends/rust.d.ts.map +1 -0
- package/build/src/backends/rust.js +344 -0
- package/build/src/backends/scalars.d.ts +14 -6
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +167 -17
- package/build/src/backends/shared.d.ts +23 -4
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +2158 -62
- package/build/src/backends/stdlib-support.d.ts +14 -0
- package/build/src/backends/stdlib-support.d.ts.map +1 -0
- package/build/src/backends/stdlib-support.js +237 -0
- package/build/src/backends/swift-runtime.d.ts +3 -0
- package/build/src/backends/swift-runtime.d.ts.map +1 -0
- package/build/src/backends/swift-runtime.js +14 -0
- package/build/src/backends/swift.d.ts +8 -0
- package/build/src/backends/swift.d.ts.map +1 -0
- package/build/src/backends/swift.js +127 -0
- package/build/src/backends/typescript.d.ts.map +1 -1
- package/build/src/backends/typescript.js +344 -24
- package/build/src/backends/wasm.d.ts +43 -0
- package/build/src/backends/wasm.d.ts.map +1 -0
- package/build/src/backends/wasm.js +2164 -0
- package/build/src/backends/writer.d.ts +235 -4
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +468 -3
- package/build/src/diagnostic.d.ts +4 -3
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +5 -3
- package/build/src/frontends/c.d.ts.map +1 -1
- package/build/src/frontends/c.js +5 -3
- package/build/src/frontends/cpp.d.ts.map +1 -1
- package/build/src/frontends/cpp.js +5 -3
- package/build/src/frontends/csharp.d.ts.map +1 -1
- package/build/src/frontends/csharp.js +7 -3
- package/build/src/frontends/dart.d.ts +10 -0
- package/build/src/frontends/dart.d.ts.map +1 -0
- package/build/src/frontends/dart.js +913 -0
- package/build/src/frontends/index.d.ts +3 -1
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +15 -5
- package/build/src/frontends/java.d.ts +110 -1
- package/build/src/frontends/java.d.ts.map +1 -1
- package/build/src/frontends/java.js +1725 -70
- package/build/src/frontends/javascript-typescript.d.ts +69 -1
- package/build/src/frontends/javascript-typescript.d.ts.map +1 -1
- package/build/src/frontends/javascript-typescript.js +1825 -93
- package/build/src/frontends/kotlin.d.ts +10 -0
- package/build/src/frontends/kotlin.d.ts.map +1 -0
- package/build/src/frontends/kotlin.js +685 -0
- package/build/src/frontends/php.d.ts +118 -1
- package/build/src/frontends/php.d.ts.map +1 -1
- package/build/src/frontends/php.js +1583 -76
- package/build/src/frontends/program.d.ts +74 -0
- package/build/src/frontends/program.d.ts.map +1 -0
- package/build/src/frontends/program.js +989 -0
- package/build/src/frontends/ruby.d.ts +68 -1
- package/build/src/frontends/ruby.d.ts.map +1 -1
- package/build/src/frontends/ruby.js +1446 -101
- package/build/src/frontends/rust-parser.d.ts +11 -0
- package/build/src/frontends/rust-parser.d.ts.map +1 -0
- package/build/src/frontends/rust-parser.js +15 -0
- package/build/src/frontends/rust.d.ts +14 -0
- package/build/src/frontends/rust.d.ts.map +1 -0
- package/build/src/frontends/rust.js +715 -0
- package/build/src/frontends/scalars.d.ts +10 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +28 -2
- package/build/src/frontends/swift.d.ts +10 -0
- package/build/src/frontends/swift.d.ts.map +1 -0
- package/build/src/frontends/swift.js +860 -0
- package/build/src/frontends/types.d.ts +186 -0
- package/build/src/frontends/types.d.ts.map +1 -0
- package/build/src/frontends/types.js +634 -0
- package/build/src/language-registry.d.ts +46 -4
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +167 -13
- package/build/src/mapping.d.ts +2 -2
- package/build/src/mapping.d.ts.map +1 -1
- package/build/src/mapping.js +31 -10
- package/build/src/semantic/capabilities.d.ts +66 -0
- package/build/src/semantic/capabilities.d.ts.map +1 -0
- package/build/src/semantic/capabilities.js +649 -0
- package/build/src/semantic/effects.d.ts +26 -0
- package/build/src/semantic/effects.d.ts.map +1 -0
- package/build/src/semantic/effects.js +764 -0
- package/build/src/semantic/generics.d.ts +23 -0
- package/build/src/semantic/generics.d.ts.map +1 -0
- package/build/src/semantic/generics.js +61 -0
- package/build/src/semantic/lifetime.d.ts +37 -0
- package/build/src/semantic/lifetime.d.ts.map +1 -0
- package/build/src/semantic/lifetime.js +527 -0
- package/build/src/semantic/provenance.d.ts +9 -2
- package/build/src/semantic/provenance.d.ts.map +1 -1
- package/build/src/semantic/provenance.js +462 -20
- package/build/src/semantic/scalars.d.ts +11 -0
- package/build/src/semantic/scalars.d.ts.map +1 -1
- package/build/src/semantic/scalars.js +16 -1
- package/build/src/semantic/stdlib.d.ts +254 -0
- package/build/src/semantic/stdlib.d.ts.map +1 -0
- package/build/src/semantic/stdlib.js +880 -0
- package/build/src/semantic/types.d.ts +2952 -202
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +688 -15
- package/build/src/semantic/validate.d.ts +85 -5
- package/build/src/semantic/validate.d.ts.map +1 -1
- package/build/src/semantic/validate.js +2576 -98
- package/build/src/stdlib-facades.d.ts +304 -0
- package/build/src/stdlib-facades.d.ts.map +1 -0
- package/build/src/stdlib-facades.js +1167 -0
- package/build/src/stdlib-negotiation.d.ts +69 -0
- package/build/src/stdlib-negotiation.d.ts.map +1 -0
- package/build/src/stdlib-negotiation.js +403 -0
- package/build/src/stdlib-providers.d.ts +72 -0
- package/build/src/stdlib-providers.d.ts.map +1 -0
- package/build/src/stdlib-providers.js +339 -0
- package/build/src/toolchains.d.ts +55 -1
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +15 -4
- package/docs/architecture.md +45 -13
- package/docs/dart.md +60 -0
- package/docs/goals.md +3 -3
- package/docs/ios.md +121 -0
- package/docs/kotlin.md +42 -0
- package/docs/language-support.md +231 -26
- package/docs/multi-file-modules.md +52 -0
- package/docs/parser-qualification.md +121 -8
- package/docs/plans/2026-09-05-standard-library-portability.md +10 -10
- package/docs/rust.md +88 -0
- package/docs/source-maps.md +15 -7
- package/docs/standard-library-portability.md +39 -8
- package/docs/swift.md +44 -0
- package/docs/testing.md +366 -4
- package/docs/webassembly.md +52 -0
- package/index.js +63 -8
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +2 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/README.md +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/grammar.js +1630 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/package.json +64 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/darwin-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/linux-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-arm64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/prebuilds/win32-x64/tree-sitter-rust.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/highlights.scm +159 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/injections.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/queries/tags.scm +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/grammar.json +9405 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/node-types.json +5399 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/parser.c +192569 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/scanner.c +393 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter-rust.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-rust/tree-sitter.json +53 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +3 -2
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +5 -4
- package/package.json +5 -2
- package/src/artifact-path.js +47 -2
- package/src/artifacts.js +67 -0
- package/src/backends/c-validation.js +6 -1
- package/src/backends/cpp-validation.js +6 -1
- package/src/backends/csharp.js +3 -0
- package/src/backends/dart-runtime.js +41 -0
- package/src/backends/dart.js +326 -0
- package/src/backends/effects.js +705 -0
- package/src/backends/go.js +14 -2
- package/src/backends/identifiers.js +160 -9
- package/src/backends/index.js +27 -2
- package/src/backends/ios.js +1612 -0
- package/src/backends/java.js +454 -36
- package/src/backends/javascript.js +389 -23
- package/src/backends/kotlin-runtime.js +29 -0
- package/src/backends/kotlin.js +141 -0
- package/src/backends/native-validation.js +1 -1
- package/src/backends/ordered-expressions.js +40 -6
- package/src/backends/php-stdlib-support.js +239 -0
- package/src/backends/php.js +469 -32
- package/src/backends/program.js +1407 -0
- package/src/backends/python.js +3 -0
- package/src/backends/ruby.js +326 -23
- package/src/backends/rust-runtime.js +34 -0
- package/src/backends/rust-validation.js +75 -0
- package/src/backends/rust.js +335 -0
- package/src/backends/scalars.js +141 -16
- package/src/backends/shared.js +2304 -124
- package/src/backends/stdlib-support.js +234 -0
- package/src/backends/swift-runtime.js +14 -0
- package/src/backends/swift.js +132 -0
- package/src/backends/typescript.js +349 -23
- package/src/backends/wasm.js +2208 -0
- package/src/backends/writer.js +520 -2
- package/src/diagnostic.js +4 -2
- package/src/frontends/c.js +4 -2
- package/src/frontends/cpp.js +4 -2
- package/src/frontends/csharp.js +4 -2
- package/src/frontends/dart.js +963 -0
- package/src/frontends/index.js +14 -4
- package/src/frontends/java.js +1977 -69
- package/src/frontends/javascript-typescript.js +2046 -102
- package/src/frontends/kotlin.js +713 -0
- package/src/frontends/php.js +1725 -79
- package/src/frontends/program.js +1062 -0
- package/src/frontends/ruby.js +1624 -98
- package/src/frontends/rust-parser.js +18 -0
- package/src/frontends/rust.js +714 -0
- package/src/frontends/scalars.js +31 -1
- package/src/frontends/swift.js +893 -0
- package/src/frontends/types.js +750 -0
- package/src/language-registry.js +172 -12
- package/src/mapping.js +33 -9
- package/src/semantic/capabilities.js +671 -0
- package/src/semantic/effects.js +737 -0
- package/src/semantic/generics.js +58 -0
- package/src/semantic/lifetime.js +517 -0
- package/src/semantic/provenance.js +412 -19
- package/src/semantic/scalars.js +17 -0
- package/src/semantic/stdlib.js +921 -0
- package/src/semantic/types.js +765 -14
- package/src/semantic/validate.js +2934 -209
- package/src/stdlib-facades.js +1211 -0
- package/src/stdlib-negotiation.js +446 -0
- package/src/stdlib-providers.js +377 -0
- package/src/toolchains.js +16 -3
|
@@ -1,16 +1,26 @@
|
|
|
1
1
|
// @ts-check
|
|
2
2
|
import { parse as parseBabel } from "@babel/parser";
|
|
3
3
|
import { parse as parseComment } from "comment-parser";
|
|
4
|
-
import { missingType, parseFailure, unsupportedSyntax } from "../diagnostic.js";
|
|
4
|
+
import { missingType, parseFailure, SemantifoldDiagnostic, 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
9
|
import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
|
|
9
|
-
import {
|
|
10
|
+
import { isTask034ResourceProbe } from "../semantic/capabilities.js";
|
|
11
|
+
import { hasExactEffectSupport } from "../backends/effects.js";
|
|
12
|
+
import { requireSourceReturnType, requireSourceScalarType } from "./scalars.js";
|
|
13
|
+
import { documentedValueType, instantiatedRecordFieldType, iterationBindingType, iterationOperandType, knownCallReturnType, listType, mapType, optionalType, orderedMapTypeFromMap, ownedReferenceType, ownedResourceType, preservesGenericOptionalEvidence, recordType, referenceType, typeVariable } from "./types.js";
|
|
10
14
|
/** @typedef {NonNullable<import("@babel/parser").ParseResult<import("@babel/types").File>["tokens"]>[number]} BabelToken */
|
|
11
15
|
/** @typedef {{byStart: Map<number, BabelToken>, tokens: BabelToken[]}} BabelTokenIndex */
|
|
16
|
+
/** @typedef {{name: string, nameLocation: import("../semantic/types.js").SourceLocation, parameters: import("../semantic/types.js").Parameter[], returnType: import("../semantic/types.js").SemanticFunctionReturnType, typeParameters?: import("../semantic/types.js").TypeParameter[], location: import("../semantic/types.js").SourceLocation}} JavaScriptFunctionSignature */
|
|
17
|
+
/** @typedef {{bindings: Map<string, import("../semantic/types.js").SemanticBindingType>, classes: Map<string, import("../semantic/types.js").ClassDeclaration>, currentClass?: import("../semantic/types.js").ClassDeclaration, errors: Map<string, import("../semantic/types.js").ErrorDeclaration>, errorNames: Map<string, import("../semantic/types.js").ErrorDeclaration>, functions: Map<string, JavaScriptFunctionSignature>, lexicalValueNames?: Set<string>, orderedMapDeclarations?: Set<object>, recordNames: Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>, records: Map<string, import("../semantic/types.js").RecordDeclaration>, returnType?: import("../semantic/types.js").SemanticFunctionReturnType, typeParameters?: Map<string, import("../semantic/types.js").TypeParameter>, valueRecordNames: Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>}} JavaScriptConversionContext */
|
|
12
18
|
/** @type {WeakMap<object, BabelTokenIndex>} */
|
|
13
19
|
const nodeTokens = new WeakMap();
|
|
20
|
+
const referenceMethodHooks = new Set([
|
|
21
|
+
"__defineGetter__", "__defineSetter__", "__lookupGetter__", "__lookupSetter__", "__proto__", "constructor",
|
|
22
|
+
"hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", "toLocaleString", "toString", "valueOf"
|
|
23
|
+
]);
|
|
14
24
|
const babelBinaryOperations = new Map([
|
|
15
25
|
["+", "Add"],
|
|
16
26
|
["-", "Subtract"],
|
|
@@ -107,9 +117,26 @@ function commentTagLocation(comment, tag, field, filename, source) {
|
|
|
107
117
|
}
|
|
108
118
|
const orderedFields = ["start", "delimiter", "postDelimiter", "tag", "postTag", "type", "postType", "name"];
|
|
109
119
|
const fieldIndex = orderedFields.indexOf(field);
|
|
110
|
-
|
|
120
|
+
let start = lineStart + orderedFields.slice(0, fieldIndex).reduce((length, key) => length + line.tokens[ /** @type {keyof typeof line.tokens} */(key)].length, 0);
|
|
111
121
|
const token = line.tokens[field];
|
|
112
|
-
|
|
122
|
+
let length = token.length;
|
|
123
|
+
if (field == "type" && tag.type) {
|
|
124
|
+
const nestedOffset = token.indexOf(tag.type);
|
|
125
|
+
if (nestedOffset < 0)
|
|
126
|
+
throw new Error(`Comment parser omitted the @${tag.tag} type spelling.`);
|
|
127
|
+
start += nestedOffset;
|
|
128
|
+
length = tag.type.length;
|
|
129
|
+
}
|
|
130
|
+
return locationFromOffsets(filename, source, start, start + length);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Reports whether `Map` resolves to the native intrinsic in the current lexical scope.
|
|
134
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
135
|
+
* @returns {boolean} Whether native Map construction is unshadowed.
|
|
136
|
+
*/
|
|
137
|
+
function nativeMapAvailable(context) {
|
|
138
|
+
return !context.bindings.has("Map") && !context.lexicalValueNames?.has("Map") &&
|
|
139
|
+
!context.functions.has("Map") && !context.valueRecordNames.has("Map") && !context.errorNames.has("Map");
|
|
113
140
|
}
|
|
114
141
|
/**
|
|
115
142
|
* Converts a supported Babel expression.
|
|
@@ -117,14 +144,52 @@ function commentTagLocation(comment, tag, field, filename, source) {
|
|
|
117
144
|
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
118
145
|
* @param {string} filename - Source filename.
|
|
119
146
|
* @param {string} source - Complete source.
|
|
147
|
+
* @param {JavaScriptConversionContext} [context] - Typed lexical conversion context.
|
|
148
|
+
* @param {import("../semantic/types.js").SemanticValueType} [expectedType] - Explicit contextual value type.
|
|
149
|
+
* @param {boolean} [preserveOptional] - Whether an optional identifier remains wrapped.
|
|
120
150
|
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
121
151
|
*/
|
|
122
|
-
function convertExpression(node, language, filename, source) {
|
|
152
|
+
function convertExpression(node, language, filename, source, context = { bindings: new Map(), classes: new Map(), errors: new Map(), errorNames: new Map(), functions: new Map(), recordNames: new Map(), records: new Map(), valueRecordNames: new Map() }, expectedType, preserveOptional = false) {
|
|
123
153
|
const location = nodeLocation(node, filename, source);
|
|
154
|
+
if (node.type == "Identifier" && node.name == "undefined") {
|
|
155
|
+
return unsupportedSyntax(language, "undefined absence value", location);
|
|
156
|
+
}
|
|
157
|
+
if (expectedType?.kind == "OptionalType") {
|
|
158
|
+
if (node.type == "NullLiteral") {
|
|
159
|
+
return withParserRanges({ kind: /** @type {const} */ ("OptionalNone"), location }, { absence: location });
|
|
160
|
+
}
|
|
161
|
+
if (knownExpressionType(node, context, language, filename, source)?.kind == "OptionalType") {
|
|
162
|
+
return convertExpression(node, language, filename, source, context, undefined, true);
|
|
163
|
+
}
|
|
164
|
+
return withParserRanges({
|
|
165
|
+
kind: /** @type {const} */ ("OptionalSome"),
|
|
166
|
+
location,
|
|
167
|
+
value: convertExpression(node, language, filename, source, context, expectedType.valueType)
|
|
168
|
+
}, { some: location });
|
|
169
|
+
}
|
|
170
|
+
if (node.type == "NullLiteral")
|
|
171
|
+
return unsupportedSyntax(language, "null outside an explicit optional context", location);
|
|
172
|
+
if (node.type == "TSNonNullExpression") {
|
|
173
|
+
const expression = convertExpression(node.expression, language, filename, source, context);
|
|
174
|
+
if (language != "typescript" || expression.kind != "MapLookupExpression") {
|
|
175
|
+
return unsupportedSyntax(language, "non-null assertion other than Map.get result", location);
|
|
176
|
+
}
|
|
177
|
+
expression.location = location;
|
|
178
|
+
return expression;
|
|
179
|
+
}
|
|
124
180
|
if (node.type == "Identifier") {
|
|
125
|
-
|
|
181
|
+
const identifier = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name: node.name }, {
|
|
126
182
|
name: identifierLocation(node, filename, source)
|
|
127
183
|
});
|
|
184
|
+
if (!preserveOptional && context.bindings.get(node.name)?.kind == "OptionalType") {
|
|
185
|
+
return withParserRanges({ kind: /** @type {const} */ ("OptionalUnwrap"), location, operand: identifier }, { unwrap: location });
|
|
186
|
+
}
|
|
187
|
+
return identifier;
|
|
188
|
+
}
|
|
189
|
+
if (node.type == "ThisExpression") {
|
|
190
|
+
if (!context.currentClass)
|
|
191
|
+
return unsupportedSyntax(language, "receiver outside a reference class", location);
|
|
192
|
+
return withParserRanges({ classId: /** @type {string} */ (context.currentClass.id), kind: /** @type {const} */ ("ReceiverExpression"), location }, { receiver: location });
|
|
128
193
|
}
|
|
129
194
|
if (node.type == "NumericLiteral") {
|
|
130
195
|
if (!Number.isSafeInteger(node.value))
|
|
@@ -142,6 +207,186 @@ function convertExpression(node, language, filename, source) {
|
|
|
142
207
|
}
|
|
143
208
|
return withParserRanges({ kind: /** @type {const} */ ("StringLiteral"), location, value: node.value }, { literal: location });
|
|
144
209
|
}
|
|
210
|
+
if (node.type == "ArrayExpression") {
|
|
211
|
+
const elementType = expectedType?.kind == "ListType" ? expectedType.elementType : undefined;
|
|
212
|
+
const elements = node.elements.map((element, index) => {
|
|
213
|
+
if (!element)
|
|
214
|
+
return unsupportedSyntax(language, "sparse array hole", arrayHoleLocation(node, index, filename, source));
|
|
215
|
+
if (element.type == "SpreadElement")
|
|
216
|
+
return unsupportedSyntax(language, "array spread", nodeLocation(element, filename, source));
|
|
217
|
+
return convertExpression(element, language, filename, source, context, elementType);
|
|
218
|
+
});
|
|
219
|
+
return withParserRanges({ elements, kind: /** @type {const} */ ("ListLiteral"), location }, { literal: location });
|
|
220
|
+
}
|
|
221
|
+
if (node.type == "NewExpression" && node.callee.type == "Identifier" && node.callee.name == "Map") {
|
|
222
|
+
if (!nativeMapAvailable(context)) {
|
|
223
|
+
return unsupportedSyntax(language, "shadowed Map constructor", identifierLocation(node.callee, filename, source));
|
|
224
|
+
}
|
|
225
|
+
if (expectedType?.kind == "RecordType")
|
|
226
|
+
return unsupportedSyntax(language, "Map used as a structural record substitute", location);
|
|
227
|
+
if (node.typeArguments || node.typeParameters || node.arguments.length > 1) {
|
|
228
|
+
return unsupportedSyntax(language, "generic or invalid Map construction", location);
|
|
229
|
+
}
|
|
230
|
+
const initializer = node.arguments[0];
|
|
231
|
+
if (!initializer)
|
|
232
|
+
return withParserRanges({
|
|
233
|
+
entries: [],
|
|
234
|
+
kind: expectedType?.kind == "OrderedMapType"
|
|
235
|
+
? /** @type {const} */ ("OrderedMapLiteral")
|
|
236
|
+
: /** @type {const} */ ("MapLiteral"),
|
|
237
|
+
location
|
|
238
|
+
}, { literal: location });
|
|
239
|
+
if (initializer.type == "SpreadElement" || initializer.type == "ArgumentPlaceholder") {
|
|
240
|
+
return unsupportedSyntax(language, initializer.type, nodeLocation(initializer, filename, source));
|
|
241
|
+
}
|
|
242
|
+
if (initializer.type != "ArrayExpression") {
|
|
243
|
+
return unsupportedSyntax(language, "Map initializer other than an entry array", nodeLocation(initializer, filename, source));
|
|
244
|
+
}
|
|
245
|
+
const valueType = expectedType?.kind == "MapType" || expectedType?.kind == "OrderedMapType"
|
|
246
|
+
? expectedType.valueType : undefined;
|
|
247
|
+
const entries = initializer.elements.map((element, index) => {
|
|
248
|
+
if (!element)
|
|
249
|
+
return unsupportedSyntax(language, "sparse map initializer", arrayHoleLocation(initializer, index, filename, source));
|
|
250
|
+
if (element.type == "SpreadElement")
|
|
251
|
+
return unsupportedSyntax(language, "map spread", nodeLocation(element, filename, source));
|
|
252
|
+
if (element.type != "ArrayExpression" || element.elements.length != 2) {
|
|
253
|
+
return unsupportedSyntax(language, "Map entry other than a key/value pair", nodeLocation(element, filename, source));
|
|
254
|
+
}
|
|
255
|
+
const [key, value] = element.elements;
|
|
256
|
+
if (!key)
|
|
257
|
+
return unsupportedSyntax(language, "sparse map key", arrayHoleLocation(element, 0, filename, source));
|
|
258
|
+
if (!value)
|
|
259
|
+
return unsupportedSyntax(language, "sparse map value", arrayHoleLocation(element, 1, filename, source));
|
|
260
|
+
if (key.type == "SpreadElement" || value.type == "SpreadElement") {
|
|
261
|
+
const spread = key.type == "SpreadElement" ? key : value;
|
|
262
|
+
return unsupportedSyntax(language, "map entry spread", nodeLocation(spread, filename, source));
|
|
263
|
+
}
|
|
264
|
+
if (key.type != "StringLiteral") {
|
|
265
|
+
return unsupportedSyntax(language, "map key other than a string literal", nodeLocation(key, filename, source));
|
|
266
|
+
}
|
|
267
|
+
const keyExpression = /** @type {import("../semantic/types.js").StringLiteral} */ (convertExpression(key, language, filename, source, context));
|
|
268
|
+
return withParserRanges({
|
|
269
|
+
key: keyExpression,
|
|
270
|
+
kind: /** @type {const} */ ("MapEntry"),
|
|
271
|
+
location: nodeLocation(element, filename, source),
|
|
272
|
+
value: convertExpression(value, language, filename, source, context, valueType)
|
|
273
|
+
}, {
|
|
274
|
+
key: keyExpression.location,
|
|
275
|
+
operator: tokenLocation(element, ",", key.end ?? element.start ?? 0, value.start ?? element.end ?? source.length, filename, source)
|
|
276
|
+
});
|
|
277
|
+
});
|
|
278
|
+
return withParserRanges({
|
|
279
|
+
entries,
|
|
280
|
+
kind: expectedType?.kind == "OrderedMapType"
|
|
281
|
+
? /** @type {const} */ ("OrderedMapLiteral")
|
|
282
|
+
: /** @type {const} */ ("MapLiteral"),
|
|
283
|
+
location
|
|
284
|
+
}, { literal: location });
|
|
285
|
+
}
|
|
286
|
+
if (node.type == "NewExpression" && node.callee.type == "Identifier" && context.valueRecordNames.has(node.callee.name)) {
|
|
287
|
+
const declaration = /** @type {import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration} */ (context.valueRecordNames.get(node.callee.name));
|
|
288
|
+
if (declaration.kind == "ClassDeclaration") {
|
|
289
|
+
if (node.typeArguments || node.typeParameters)
|
|
290
|
+
return unsupportedSyntax(language, "generic reference construction", location);
|
|
291
|
+
const arguments_ = node.arguments.map((argument, index) => {
|
|
292
|
+
if (argument.type == "SpreadElement" || argument.type == "ArgumentPlaceholder") {
|
|
293
|
+
return unsupportedSyntax(language, argument.type, nodeLocation(argument, filename, source));
|
|
294
|
+
}
|
|
295
|
+
return convertExpression(argument, language, filename, source, context, declaration.constructor.parameters[index]?.type);
|
|
296
|
+
});
|
|
297
|
+
const classLocation = identifierLocation(node.callee, filename, source);
|
|
298
|
+
return withParserRanges({ arguments: arguments_, kind: /** @type {const} */ ("ReferenceConstruction"), location,
|
|
299
|
+
reference: declaration.ownership?.kind == "ownedResource"
|
|
300
|
+
? ownedReferenceType(/** @type {string} */ (declaration.id), classLocation)
|
|
301
|
+
: referenceType(/** @type {string} */ (declaration.id), classLocation) }, { class: classLocation });
|
|
302
|
+
}
|
|
303
|
+
const sourceArguments = node.typeArguments?.params ?? node.typeParameters?.params;
|
|
304
|
+
const typeArguments = sourceArguments?.map((/** @type {import("@babel/types").TSType} */ argument) => convertTypeScriptValueTypeNode(argument, `Record '${declaration.name}' application`, location, filename, source, context.recordNames, context.typeParameters)) ?? (expectedType?.kind == "RecordType" && expectedType.declarationId == declaration.id ? expectedType.arguments : undefined);
|
|
305
|
+
const arguments_ = node.arguments.map((argument, index) => {
|
|
306
|
+
if (argument.type == "SpreadElement" || argument.type == "ArgumentPlaceholder") {
|
|
307
|
+
return unsupportedSyntax(language, argument.type, nodeLocation(argument, filename, source));
|
|
308
|
+
}
|
|
309
|
+
return convertExpression(argument, language, filename, source, context, instantiatedRecordFieldType(declaration, typeArguments, index));
|
|
310
|
+
});
|
|
311
|
+
return withParserRanges({
|
|
312
|
+
arguments: arguments_,
|
|
313
|
+
kind: /** @type {const} */ ("RecordConstruction"),
|
|
314
|
+
location,
|
|
315
|
+
record: recordType(/** @type {string} */ (declaration.id), identifierLocation(node.callee, filename, source), typeArguments)
|
|
316
|
+
}, { record: identifierLocation(node.callee, filename, source) });
|
|
317
|
+
}
|
|
318
|
+
if (node.type == "MemberExpression" && !node.optional && node.object.type != "Super") {
|
|
319
|
+
if (!node.computed && node.object.type == "ThisExpression" && context.currentClass) {
|
|
320
|
+
/** @type {import("@babel/types").Identifier | undefined} */
|
|
321
|
+
let property;
|
|
322
|
+
if (language == "javascript" && node.property.type == "PrivateName")
|
|
323
|
+
property = node.property.id;
|
|
324
|
+
if (language == "typescript" && node.property.type == "Identifier")
|
|
325
|
+
property = node.property;
|
|
326
|
+
if (!property)
|
|
327
|
+
return unsupportedSyntax(language, "noncanonical private instance field access", location);
|
|
328
|
+
const field = context.currentClass.fields.find((candidate) => candidate.name == property.name);
|
|
329
|
+
if (!field)
|
|
330
|
+
return unsupportedSyntax(language, `unknown private field '${property.name}'`, identifierLocation(property, filename, source));
|
|
331
|
+
return withParserRanges({ field: /** @type {string} */ (field.id), kind: /** @type {const} */ ("PrivateFieldRead"), location,
|
|
332
|
+
receiver: /** @type {import("../semantic/types.js").ReceiverExpression} */ (convertExpression(node.object, language, filename, source, context)) }, { member: identifierLocation(property, filename, source) });
|
|
333
|
+
}
|
|
334
|
+
if (knownValueExpressionType(node.object, context, language, filename, source)?.kind == "ReferenceType") {
|
|
335
|
+
return unsupportedSyntax(language, "private reference-class field access", location);
|
|
336
|
+
}
|
|
337
|
+
if (!node.computed && node.object.type == "Identifier" && node.property.type == "Identifier" &&
|
|
338
|
+
node.property.name == "message" && context.bindings.get(node.object.name)?.kind == "ErrorType") {
|
|
339
|
+
const receiverLocation = identifierLocation(node.object, filename, source);
|
|
340
|
+
return withParserRanges({
|
|
341
|
+
kind: /** @type {const} */ ("ErrorMessageRead"),
|
|
342
|
+
location,
|
|
343
|
+
receiver: withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: receiverLocation, name: node.object.name }, {
|
|
344
|
+
name: receiverLocation
|
|
345
|
+
})
|
|
346
|
+
}, { member: identifierLocation(node.property, filename, source) });
|
|
347
|
+
}
|
|
348
|
+
if (node.computed) {
|
|
349
|
+
if (knownValueExpressionType(node.object, context, language, filename, source)?.kind == "RecordType") {
|
|
350
|
+
return unsupportedSyntax(language, "computed record member access", nodeLocation(node.property, filename, source));
|
|
351
|
+
}
|
|
352
|
+
if (node.property.type == "PrivateName")
|
|
353
|
+
return unsupportedSyntax(language, node.property.type, location);
|
|
354
|
+
return withParserRanges({
|
|
355
|
+
collection: convertExpression(node.object, language, filename, source, context),
|
|
356
|
+
index: convertExpression(node.property, language, filename, source, context),
|
|
357
|
+
kind: /** @type {const} */ ("ListIndexExpression"),
|
|
358
|
+
location,
|
|
359
|
+
totality: /** @type {const} */ ("proven")
|
|
360
|
+
}, {
|
|
361
|
+
operator: tokenLocation(node, "[", node.object.end ?? node.start ?? 0, node.property.start ?? node.end ?? source.length, filename, source)
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
if (node.property.type == "Identifier" && ["length", "size"].includes(node.property.name)) {
|
|
365
|
+
const receiverType = knownValueExpressionType(node.object, context, language, filename, source);
|
|
366
|
+
if (receiverType?.kind == "RecordType") {
|
|
367
|
+
return withParserRanges({
|
|
368
|
+
field: node.property.name,
|
|
369
|
+
kind: /** @type {const} */ ("MemberRead"),
|
|
370
|
+
location,
|
|
371
|
+
receiver: convertExpression(node.object, language, filename, source, context)
|
|
372
|
+
}, { member: identifierLocation(node.property, filename, source) });
|
|
373
|
+
}
|
|
374
|
+
return withParserRanges({
|
|
375
|
+
collection: convertExpression(node.object, language, filename, source, context),
|
|
376
|
+
collectionKind: /** @type {"list" | "map"} */ (node.property.name == "length" ? "list" : "map"),
|
|
377
|
+
kind: /** @type {const} */ ("CollectionSizeExpression"),
|
|
378
|
+
location
|
|
379
|
+
}, { operator: identifierLocation(node.property, filename, source) });
|
|
380
|
+
}
|
|
381
|
+
if (node.property.type == "Identifier") {
|
|
382
|
+
return withParserRanges({
|
|
383
|
+
field: node.property.name,
|
|
384
|
+
kind: /** @type {const} */ ("MemberRead"),
|
|
385
|
+
location,
|
|
386
|
+
receiver: convertExpression(node.object, language, filename, source, context)
|
|
387
|
+
}, { member: identifierLocation(node.property, filename, source) });
|
|
388
|
+
}
|
|
389
|
+
}
|
|
145
390
|
if (node.type == "TemplateLiteral") {
|
|
146
391
|
if (node.expressions.length > 0)
|
|
147
392
|
return unsupportedSyntax(language, "interpolated string", location);
|
|
@@ -152,7 +397,7 @@ function convertExpression(node, language, filename, source) {
|
|
|
152
397
|
return withParserRanges({ kind: /** @type {const} */ ("StringLiteral"), location, value: quasi.value.cooked }, { literal: location });
|
|
153
398
|
}
|
|
154
399
|
if (node.type == "UnaryExpression" && ["!", "-"].includes(node.operator)) {
|
|
155
|
-
const operand = convertExpression(node.argument, language, filename, source);
|
|
400
|
+
const operand = convertExpression(node.argument, language, filename, source, context);
|
|
156
401
|
const semantic = withAdaptedOperation(withParserRanges({
|
|
157
402
|
kind: "UnaryExpression",
|
|
158
403
|
location,
|
|
@@ -165,19 +410,26 @@ function convertExpression(node, language, filename, source) {
|
|
|
165
410
|
if (node.type == "LogicalExpression" && ["&&", "||"].includes(node.operator)) {
|
|
166
411
|
const semantic = withAdaptedOperation(withParserRanges({
|
|
167
412
|
kind: "BinaryExpression",
|
|
168
|
-
left: convertExpression(node.left, language, filename, source),
|
|
413
|
+
left: convertExpression(node.left, language, filename, source, context),
|
|
169
414
|
location,
|
|
170
|
-
right: convertExpression(node.right, language, filename, source)
|
|
415
|
+
right: convertExpression(node.right, language, filename, source, context)
|
|
171
416
|
}, {
|
|
172
417
|
operator: tokenLocation(node, node.operator, node.left.end ?? node.start ?? 0, node.right.start ?? node.end ?? source.length, filename, source)
|
|
173
418
|
}), node.operator == "&&" ? "And" : "Or");
|
|
174
419
|
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(semantic));
|
|
175
420
|
}
|
|
421
|
+
if (node.type == "BinaryExpression" && node.operator == "!==" && node.left.type == "Identifier" &&
|
|
422
|
+
node.right.type == "NullLiteral") {
|
|
423
|
+
const operand = /** @type {import("../semantic/types.js").IdentifierExpression} */ (convertExpression(node.left, language, filename, source, context, undefined, true));
|
|
424
|
+
return withParserRanges({ kind: /** @type {const} */ ("OptionalIsPresent"), location, operand }, {
|
|
425
|
+
operator: tokenLocation(node, node.operator, node.left.end ?? node.start ?? 0, node.right.start ?? node.end ?? source.length, filename, source)
|
|
426
|
+
});
|
|
427
|
+
}
|
|
176
428
|
if (node.type == "BinaryExpression" && babelBinaryOperations.has(node.operator)) {
|
|
177
429
|
if (node.left.type == "PrivateName")
|
|
178
430
|
unsupportedSyntax(language, node.left.type, location);
|
|
179
|
-
const left = convertExpression(node.left, language, filename, source);
|
|
180
|
-
const right = convertExpression(node.right, language, filename, source);
|
|
431
|
+
const left = convertExpression(node.left, language, filename, source, context);
|
|
432
|
+
const right = convertExpression(node.right, language, filename, source, context);
|
|
181
433
|
const semantic = withAdaptedOperation(withParserRanges({
|
|
182
434
|
kind: "BinaryExpression",
|
|
183
435
|
left,
|
|
@@ -192,31 +444,184 @@ function convertExpression(node, language, filename, source) {
|
|
|
192
444
|
return unsupportedSyntax(language, `coercive equality ${node.operator}`, location);
|
|
193
445
|
}
|
|
194
446
|
if (node.type == "CallExpression" && node.callee.type == "Identifier") {
|
|
195
|
-
|
|
447
|
+
if (node.optional || node.callee.optional || node.typeArguments || node.typeParameters) {
|
|
448
|
+
return unsupportedSyntax(language, "optional or generic call", location);
|
|
449
|
+
}
|
|
450
|
+
const signature = context.functions.get(node.callee.name);
|
|
451
|
+
const arguments_ = node.arguments.map((argument, index) => {
|
|
196
452
|
if (argument.type == "SpreadElement" || argument.type == "ArgumentPlaceholder") {
|
|
197
453
|
return unsupportedSyntax(language, argument.type, nodeLocation(argument, filename, source));
|
|
198
454
|
}
|
|
199
|
-
return convertExpression(argument, language, filename, source);
|
|
455
|
+
return convertExpression(argument, language, filename, source, context, signature?.parameters[index]?.type, preservesGenericOptionalEvidence(signature, index));
|
|
200
456
|
});
|
|
201
457
|
return withParserRanges({ arguments: arguments_, callee: node.callee.name, kind: /** @type {const} */ ("CallExpression"), location }, {
|
|
202
458
|
callee: identifierLocation(node.callee, filename, source)
|
|
203
459
|
});
|
|
204
460
|
}
|
|
461
|
+
if (node.type == "CallExpression" && !node.optional && !node.typeArguments && !node.typeParameters &&
|
|
462
|
+
node.callee.type == "MemberExpression" && !node.callee.computed && !node.callee.optional &&
|
|
463
|
+
node.callee.object.type != "Super" && node.callee.property.type == "Identifier") {
|
|
464
|
+
const receiverType = knownValueExpressionType(node.callee.object, context, language, filename, source);
|
|
465
|
+
if (receiverType?.kind == "ReferenceType" || receiverType?.kind == "OwnedReferenceType") {
|
|
466
|
+
const declaration = context.classes.get(receiverType.declarationId);
|
|
467
|
+
const methodName = node.callee.property.name;
|
|
468
|
+
const method = declaration?.methods.find((candidate) => candidate.name == methodName);
|
|
469
|
+
const arguments_ = node.arguments.map((argument, index) => {
|
|
470
|
+
if (argument.type == "SpreadElement" || argument.type == "ArgumentPlaceholder") {
|
|
471
|
+
return unsupportedSyntax(language, argument.type, nodeLocation(argument, filename, source));
|
|
472
|
+
}
|
|
473
|
+
return convertExpression(argument, language, filename, source, context, method?.parameters[index]?.type);
|
|
474
|
+
});
|
|
475
|
+
return withParserRanges({ arguments: arguments_, kind: /** @type {const} */ ("MethodCallExpression"), location,
|
|
476
|
+
method: method?.id ?? node.callee.property.name,
|
|
477
|
+
receiver: convertExpression(node.callee.object, language, filename, source, context) }, { member: identifierLocation(node.callee.property, filename, source) });
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
if (node.type == "CallExpression" && !node.optional && !node.typeArguments && !node.typeParameters &&
|
|
481
|
+
node.callee.type == "MemberExpression" && !node.callee.computed && !node.callee.optional &&
|
|
482
|
+
node.callee.object.type != "Super" && node.callee.property.type == "Identifier" &&
|
|
483
|
+
node.callee.property.name == "get") {
|
|
484
|
+
if (node.arguments.length != 1)
|
|
485
|
+
return unsupportedSyntax(language, "Map.get argument count", location);
|
|
486
|
+
const key = node.arguments[0];
|
|
487
|
+
if (key.type == "SpreadElement" || key.type == "ArgumentPlaceholder") {
|
|
488
|
+
return unsupportedSyntax(language, key.type, nodeLocation(key, filename, source));
|
|
489
|
+
}
|
|
490
|
+
return withParserRanges({
|
|
491
|
+
collection: convertExpression(node.callee.object, language, filename, source, context),
|
|
492
|
+
key: convertExpression(key, language, filename, source, context),
|
|
493
|
+
kind: /** @type {const} */ ("MapLookupExpression"),
|
|
494
|
+
location,
|
|
495
|
+
totality: /** @type {const} */ ("proven")
|
|
496
|
+
}, { operator: identifierLocation(node.callee.property, filename, source) });
|
|
497
|
+
}
|
|
205
498
|
return unsupportedSyntax(language, node.type, location);
|
|
206
499
|
}
|
|
500
|
+
/**
|
|
501
|
+
* Resolves only expression result types already established by explicit module
|
|
502
|
+
* signatures and collection bindings.
|
|
503
|
+
* @param {import("@babel/types").Expression} node - Parser-owned expression.
|
|
504
|
+
* @param {JavaScriptConversionContext} context - Typed lexical context.
|
|
505
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
506
|
+
* @param {string} filename - Source filename.
|
|
507
|
+
* @param {string} source - Complete source.
|
|
508
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType | import("../semantic/types.js").ErrorType | undefined} Known result type.
|
|
509
|
+
*/
|
|
510
|
+
function knownExpressionType(node, context, language, filename, source) {
|
|
511
|
+
if (node.type == "TSNonNullExpression")
|
|
512
|
+
return knownExpressionType(node.expression, context, language, filename, source);
|
|
513
|
+
if (node.type == "Identifier")
|
|
514
|
+
return context.bindings.get(node.name);
|
|
515
|
+
if (node.type == "CallExpression" && node.callee.type == "Identifier") {
|
|
516
|
+
const signature = context.functions.get(node.callee.name);
|
|
517
|
+
if (signature)
|
|
518
|
+
return knownCallReturnType(signature, node.arguments.map((argument) => argument.type == "SpreadElement" || argument.type == "ArgumentPlaceholder"
|
|
519
|
+
? undefined
|
|
520
|
+
: knownExpressionType(argument, context, language, filename, source)));
|
|
521
|
+
}
|
|
522
|
+
if (node.type == "NewExpression" && node.callee.type == "Identifier") {
|
|
523
|
+
const declaration = context.valueRecordNames.get(node.callee.name);
|
|
524
|
+
if (declaration?.id) {
|
|
525
|
+
if (declaration.kind == "ClassDeclaration")
|
|
526
|
+
return { declarationId: declaration.id,
|
|
527
|
+
kind: declaration.ownership?.kind == "ownedResource" ? "OwnedReferenceType" : "ReferenceType" };
|
|
528
|
+
const sourceArguments = node.typeArguments?.params ?? node.typeParameters?.params;
|
|
529
|
+
const typeArguments = sourceArguments?.map((/** @type {import("@babel/types").TSType} */ argument) => convertTypeScriptValueTypeNode(argument, `Record '${declaration.name}' application`, nodeLocation(node, filename, source), filename, source, context.recordNames, context.typeParameters));
|
|
530
|
+
return { declarationId: declaration.id, kind: "RecordType", ...(typeArguments ? { arguments: typeArguments } : {}) };
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
if (node.type == "ThisExpression" && context.currentClass?.id) {
|
|
534
|
+
return { declarationId: context.currentClass.id, kind: "ReferenceType" };
|
|
535
|
+
}
|
|
536
|
+
if (node.type == "CallExpression" && node.callee.type == "MemberExpression" && !node.callee.computed &&
|
|
537
|
+
node.callee.object.type != "Super" && node.callee.property.type == "Identifier") {
|
|
538
|
+
const receiver = knownValueExpressionType(node.callee.object, context, language, filename, source);
|
|
539
|
+
if (receiver?.kind == "ReferenceType") {
|
|
540
|
+
const methodName = node.callee.property.name;
|
|
541
|
+
return context.classes.get(receiver.declarationId)?.methods.find((method) => method.name == methodName)?.returnType;
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
if (node.type == "MemberExpression" && !node.computed && node.object.type == "ThisExpression" && context.currentClass) {
|
|
545
|
+
if (language == "javascript" && node.property.type == "PrivateName") {
|
|
546
|
+
const name = node.property.id.name;
|
|
547
|
+
return context.currentClass.fields.find((field) => field.name == name)?.type;
|
|
548
|
+
}
|
|
549
|
+
if (language == "typescript" && node.property.type == "Identifier") {
|
|
550
|
+
const name = node.property.name;
|
|
551
|
+
return context.currentClass.fields.find((field) => field.name == name)?.type;
|
|
552
|
+
}
|
|
553
|
+
return undefined;
|
|
554
|
+
}
|
|
555
|
+
if (node.type == "MemberExpression" && !node.computed && node.object.type != "Super" && node.property.type == "Identifier") {
|
|
556
|
+
const receiver = knownValueExpressionType(node.object, context, language, filename, source);
|
|
557
|
+
if (receiver?.kind != "RecordType")
|
|
558
|
+
return undefined;
|
|
559
|
+
const declaration = context.records.get(receiver.declarationId);
|
|
560
|
+
const memberName = node.property.name;
|
|
561
|
+
const index = declaration?.fields.findIndex((field) => field.name == memberName) ?? -1;
|
|
562
|
+
return declaration ? instantiatedRecordFieldType(declaration, receiver.arguments, index) : undefined;
|
|
563
|
+
}
|
|
564
|
+
if (node.type == "MemberExpression" && node.computed && node.object.type != "Super") {
|
|
565
|
+
const collectionType = knownValueExpressionType(node.object, context, language, filename, source);
|
|
566
|
+
if (collectionType?.kind == "ListType")
|
|
567
|
+
return collectionType.elementType;
|
|
568
|
+
}
|
|
569
|
+
if (node.type == "CallExpression" && node.callee.type == "MemberExpression" &&
|
|
570
|
+
!node.callee.computed && node.callee.object.type != "Super" &&
|
|
571
|
+
node.callee.property.type == "Identifier" && node.callee.property.name == "get") {
|
|
572
|
+
const collectionType = knownValueExpressionType(node.callee.object, context, language, filename, source);
|
|
573
|
+
if (collectionType?.kind == "MapType" || collectionType?.kind == "OrderedMapType")
|
|
574
|
+
return collectionType.valueType;
|
|
575
|
+
}
|
|
576
|
+
return undefined;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Resolves the value type produced by the frontend's implicit optional-binding unwrap.
|
|
580
|
+
* Semantic validation separately proves that the unwrap occurs only on a present path.
|
|
581
|
+
* @param {import("@babel/types").Expression} node - Parser-owned expression.
|
|
582
|
+
* @param {JavaScriptConversionContext} context - Typed lexical context.
|
|
583
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
584
|
+
* @param {string} filename - Source filename.
|
|
585
|
+
* @param {string} source - Complete source.
|
|
586
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType | import("../semantic/types.js").ErrorType | undefined} Converted value type.
|
|
587
|
+
*/
|
|
588
|
+
function knownValueExpressionType(node, context, language, filename, source) {
|
|
589
|
+
const type = knownExpressionType(node, context, language, filename, source);
|
|
590
|
+
return node.type == "Identifier" && type?.kind == "OptionalType" ? type.valueType : type;
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Returns a stable parser-bounded location for one absent array element.
|
|
594
|
+
* @param {import("@babel/types").ArrayExpression} node - Array expression.
|
|
595
|
+
* @param {number} index - Missing element index.
|
|
596
|
+
* @param {string} filename - Source filename.
|
|
597
|
+
* @param {string} source - Complete source.
|
|
598
|
+
* @returns {import("../semantic/types.js").SourceLocation} Hole location.
|
|
599
|
+
*/
|
|
600
|
+
function arrayHoleLocation(node, index, filename, source) {
|
|
601
|
+
const previous = node.elements.slice(0, index).findLast((element) => element != null);
|
|
602
|
+
const next = node.elements.slice(index + 1).find((element) => element != null);
|
|
603
|
+
const start = previous?.end ?? (node.start ?? 0) + 1;
|
|
604
|
+
const end = next?.start ?? Math.max(start + 1, (node.end ?? source.length) - 1);
|
|
605
|
+
return locationFromOffsets(filename, source, start, Math.max(start + 1, Math.min(end, source.length)));
|
|
606
|
+
}
|
|
207
607
|
/**
|
|
208
608
|
* Converts a supported return statement.
|
|
209
609
|
* @param {import("@babel/types").Statement} node - Babel statement.
|
|
210
610
|
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
211
611
|
* @param {string} filename - Source filename.
|
|
212
612
|
* @param {string} source - Complete source.
|
|
613
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
213
614
|
* @returns {import("../semantic/types.js").ReturnStatement} Semantic return.
|
|
214
615
|
*/
|
|
215
|
-
function convertReturn(node, language, filename, source) {
|
|
616
|
+
function convertReturn(node, language, filename, source, context) {
|
|
216
617
|
const location = nodeLocation(node, filename, source);
|
|
217
|
-
if (node.type != "ReturnStatement"
|
|
618
|
+
if (node.type != "ReturnStatement")
|
|
218
619
|
return unsupportedSyntax(language, node.type, location);
|
|
219
|
-
return {
|
|
620
|
+
return {
|
|
621
|
+
...(node.argument ? { expression: convertExpression(node.argument, language, filename, source, context, context.returnType?.kind == "TypeReference" && context.returnType.name == "void" ? undefined : context.returnType) } : {}),
|
|
622
|
+
kind: "ReturnStatement",
|
|
623
|
+
location
|
|
624
|
+
};
|
|
220
625
|
}
|
|
221
626
|
/**
|
|
222
627
|
* Converts one supported local declaration or assignment.
|
|
@@ -224,9 +629,10 @@ function convertReturn(node, language, filename, source) {
|
|
|
224
629
|
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
225
630
|
* @param {string} filename - Source filename.
|
|
226
631
|
* @param {string} source - Complete source.
|
|
227
|
-
* @
|
|
632
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
633
|
+
* @returns {import("../semantic/types.js").LocalStatement | import("../semantic/types.js").PrivateFieldWriteStatement} Semantic local or private-field statement.
|
|
228
634
|
*/
|
|
229
|
-
function convertLocalStatement(node, language, filename, source) {
|
|
635
|
+
function convertLocalStatement(node, language, filename, source, context) {
|
|
230
636
|
const location = nodeLocation(node, filename, source);
|
|
231
637
|
if (node.type == "VariableDeclaration") {
|
|
232
638
|
if (!["let", "const"].includes(node.kind) || node.declarations.length != 1) {
|
|
@@ -238,12 +644,17 @@ function convertLocalStatement(node, language, filename, source) {
|
|
|
238
644
|
return unsupportedSyntax(language, declarator.id.type, declaratorLocation);
|
|
239
645
|
if (!declarator.init)
|
|
240
646
|
return unsupportedSyntax(language, "uninitialized declaration", declaratorLocation);
|
|
241
|
-
|
|
242
|
-
? convertTypeScriptType(declarator.id.typeAnnotation, `Local '${declarator.id.name}'`, declaratorLocation, filename, source)
|
|
243
|
-
: localJavaScriptType(node, declarator.id.name, filename, source);
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
647
|
+
let type = language == "typescript"
|
|
648
|
+
? convertTypeScriptType(declarator.id.typeAnnotation, `Local '${declarator.id.name}'`, declaratorLocation, filename, source, context.recordNames, context.typeParameters)
|
|
649
|
+
: localJavaScriptType(node, declarator.id.name, filename, source, context.recordNames, context.typeParameters);
|
|
650
|
+
if (node.kind == "const" && type.kind == "MapType" && context.orderedMapDeclarations?.has(declarator) &&
|
|
651
|
+
declarator.init.type == "NewExpression" && declarator.init.callee.type == "Identifier" &&
|
|
652
|
+
declarator.init.callee.name == "Map" && nativeMapAvailable(context)) {
|
|
653
|
+
type = orderedMapTypeFromMap(type, declaratorLocation);
|
|
654
|
+
}
|
|
655
|
+
const semantic = withParserRanges({
|
|
656
|
+
initializer: convertExpression(declarator.init, language, filename, source, context, type),
|
|
657
|
+
kind: /** @type {const} */ ("LocalDeclaration"),
|
|
247
658
|
location,
|
|
248
659
|
mutable: node.kind == "let",
|
|
249
660
|
name: declarator.id.name,
|
|
@@ -252,25 +663,50 @@ function convertLocalStatement(node, language, filename, source) {
|
|
|
252
663
|
name: identifierLocation(declarator.id, filename, source),
|
|
253
664
|
operator: tokenLocation(declarator, "=", declarator.id.end ?? declarator.start ?? 0, declarator.init.start ?? declarator.end ?? source.length, filename, source)
|
|
254
665
|
});
|
|
666
|
+
context.bindings.set(declarator.id.name, type);
|
|
667
|
+
return semantic;
|
|
255
668
|
}
|
|
256
669
|
if (node.type == "ExpressionStatement" && node.expression.type == "AssignmentExpression") {
|
|
257
670
|
const assignment = node.expression;
|
|
258
671
|
const targetLocation = nodeLocation(assignment.left, filename, source);
|
|
259
672
|
if (assignment.operator != "=")
|
|
260
673
|
return unsupportedSyntax(language, `assignment ${assignment.operator}`, location);
|
|
674
|
+
if (assignment.left.type == "MemberExpression" && !assignment.left.computed &&
|
|
675
|
+
assignment.left.object.type == "ThisExpression" && context.currentClass) {
|
|
676
|
+
/** @type {import("@babel/types").Identifier | undefined} */
|
|
677
|
+
let property;
|
|
678
|
+
if (language == "javascript" && assignment.left.property.type == "PrivateName")
|
|
679
|
+
property = assignment.left.property.id;
|
|
680
|
+
if (language == "typescript" && assignment.left.property.type == "Identifier")
|
|
681
|
+
property = assignment.left.property;
|
|
682
|
+
if (!property)
|
|
683
|
+
return unsupportedSyntax(language, "noncanonical private instance field assignment", location);
|
|
684
|
+
const field = context.currentClass.fields.find((candidate) => candidate.name == property.name);
|
|
685
|
+
if (!field)
|
|
686
|
+
return unsupportedSyntax(language, `unknown private field '${property.name}'`, identifierLocation(property, filename, source));
|
|
687
|
+
return withParserRanges({
|
|
688
|
+
expression: convertExpression(assignment.right, language, filename, source, context, field.type),
|
|
689
|
+
field: /** @type {string} */ (field.id),
|
|
690
|
+
kind: /** @type {const} */ ("PrivateFieldWriteStatement"),
|
|
691
|
+
location,
|
|
692
|
+
receiver: /** @type {import("../semantic/types.js").ReceiverExpression} */ (convertExpression(assignment.left.object, language, filename, source, context))
|
|
693
|
+
}, { member: identifierLocation(property, filename, source), operator: tokenLocation(assignment, "=", assignment.left.end ?? assignment.start ?? 0, assignment.right.start ?? assignment.end ?? source.length, filename, source) });
|
|
694
|
+
}
|
|
261
695
|
if (assignment.left.type != "Identifier")
|
|
262
696
|
return unsupportedSyntax(language, assignment.left.type, targetLocation);
|
|
263
697
|
const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: targetLocation, name: assignment.left.name }, {
|
|
264
698
|
name: identifierLocation(assignment.left, filename, source)
|
|
265
699
|
});
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
700
|
+
const bindingType = context.bindings.get(assignment.left.name);
|
|
701
|
+
const semantic = withParserRanges({
|
|
702
|
+
expression: convertExpression(assignment.right, language, filename, source, context, bindingType?.kind == "ErrorType" ? undefined : bindingType),
|
|
703
|
+
kind: /** @type {const} */ ("AssignmentStatement"),
|
|
269
704
|
location,
|
|
270
705
|
target
|
|
271
706
|
}, {
|
|
272
707
|
operator: tokenLocation(assignment, "=", assignment.left.end ?? assignment.start ?? 0, assignment.right.start ?? assignment.end ?? source.length, filename, source)
|
|
273
708
|
});
|
|
709
|
+
return semantic;
|
|
274
710
|
}
|
|
275
711
|
return unsupportedSyntax(language, node.type, location);
|
|
276
712
|
}
|
|
@@ -280,9 +716,11 @@ function convertLocalStatement(node, language, filename, source) {
|
|
|
280
716
|
* @param {string} name - Local name.
|
|
281
717
|
* @param {string} filename - Source filename.
|
|
282
718
|
* @param {string} source - Complete source.
|
|
283
|
-
* @
|
|
719
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
|
|
720
|
+
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
721
|
+
* @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
|
|
284
722
|
*/
|
|
285
|
-
function localJavaScriptType(node, name, filename, source) {
|
|
723
|
+
function localJavaScriptType(node, name, filename, source, recordNames, typeParameters = new Map()) {
|
|
286
724
|
const comment = node.leadingComments?.at(-1);
|
|
287
725
|
const location = nodeLocation(node, filename, source);
|
|
288
726
|
if (!comment || comment.type != "CommentBlock" || !comment.value.startsWith("*")) {
|
|
@@ -295,7 +733,7 @@ function localJavaScriptType(node, name, filename, source) {
|
|
|
295
733
|
const block = parseComment(`/*${comment.value}*/`)[0];
|
|
296
734
|
const tags = block?.tags.filter((tag) => tag.tag == "type") ?? [];
|
|
297
735
|
const tag = tags.length == 1 ? tags[0] : undefined;
|
|
298
|
-
return convertType(tag?.type, "javascript", `Local '${name}'`, location, tag ? commentTagLocation(comment, tag, "type", filename, source) : location);
|
|
736
|
+
return convertType(tag?.type, "javascript", `Local '${name}'`, location, source, tag ? commentTagLocation(comment, tag, "type", filename, source) : location, recordNames, typeParameters);
|
|
299
737
|
}
|
|
300
738
|
/**
|
|
301
739
|
* Converts one exhaustive Babel statement.
|
|
@@ -304,20 +742,236 @@ function localJavaScriptType(node, name, filename, source) {
|
|
|
304
742
|
* @param {string} filename - Source filename.
|
|
305
743
|
* @param {string} source - Complete source.
|
|
306
744
|
* @param {boolean} canonicalZeroRequired - Whether generated scalar output may contain signed zero.
|
|
745
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
307
746
|
* @returns {import("../semantic/types.js").Statement} Semantic statement.
|
|
308
747
|
*/
|
|
309
|
-
function convertStatement(node, language, filename, source, canonicalZeroRequired) {
|
|
748
|
+
function convertStatement(node, language, filename, source, canonicalZeroRequired, context) {
|
|
310
749
|
if (node.type == "ReturnStatement")
|
|
311
|
-
return convertReturn(node, language, filename, source);
|
|
750
|
+
return convertReturn(node, language, filename, source, context);
|
|
312
751
|
if (node.type == "IfStatement")
|
|
313
|
-
return convertIf(node, language, filename, source, canonicalZeroRequired);
|
|
752
|
+
return convertIf(node, language, filename, source, canonicalZeroRequired, context);
|
|
753
|
+
if (node.type == "ThrowStatement")
|
|
754
|
+
return convertTypedThrow(node, language, filename, source, context);
|
|
755
|
+
if (node.type == "TryStatement")
|
|
756
|
+
return convertTypedTry(node, language, filename, source, canonicalZeroRequired, context);
|
|
757
|
+
if (node.type == "WhileStatement")
|
|
758
|
+
return convertWhile(node, language, filename, source, canonicalZeroRequired, context);
|
|
759
|
+
if (node.type == "ForOfStatement")
|
|
760
|
+
return convertForEach(node, language, filename, source, canonicalZeroRequired, context);
|
|
761
|
+
if (node.type == "BreakStatement" || node.type == "ContinueStatement") {
|
|
762
|
+
if (node.label)
|
|
763
|
+
return unsupportedSyntax(language, `labeled ${node.type == "BreakStatement" ? "break" : "continue"}`, nodeLocation(node.label, filename, source));
|
|
764
|
+
const keyword = node.type == "BreakStatement" ? "break" : "continue";
|
|
765
|
+
const location = tokenLocation(node, keyword, node.start ?? 0, node.end ?? source.length, filename, source);
|
|
766
|
+
return withParserRanges({ kind: node.type, location }, { keyword: location });
|
|
767
|
+
}
|
|
314
768
|
if (node.type == "VariableDeclaration" || node.type == "ExpressionStatement" && node.expression.type == "AssignmentExpression") {
|
|
315
|
-
return convertLocalStatement(node, language, filename, source);
|
|
769
|
+
return convertLocalStatement(node, language, filename, source, context);
|
|
770
|
+
}
|
|
771
|
+
if (node.type == "ExpressionStatement") {
|
|
772
|
+
if (node.expression.type == "CallExpression" && (node.expression.callee.type == "Identifier" ||
|
|
773
|
+
node.expression.callee.type == "MemberExpression" && !node.expression.callee.computed &&
|
|
774
|
+
node.expression.callee.object.type != "Super" &&
|
|
775
|
+
["ReferenceType", "OwnedReferenceType"].includes(String(knownValueExpressionType(node.expression.callee.object, context, language, filename, source)?.kind)))) {
|
|
776
|
+
return {
|
|
777
|
+
expression: /** @type {import("../semantic/types.js").CallExpression | import("../semantic/types.js").MethodCallExpression} */ (convertExpression(node.expression, language, filename, source, context)),
|
|
778
|
+
kind: "ExpressionStatement",
|
|
779
|
+
location: nodeLocation(node, filename, source)
|
|
780
|
+
};
|
|
781
|
+
}
|
|
782
|
+
return convertPrint(node, language, filename, source, canonicalZeroRequired, context);
|
|
316
783
|
}
|
|
317
|
-
if (node.type == "ExpressionStatement")
|
|
318
|
-
return convertPrint(node, language, filename, source, canonicalZeroRequired);
|
|
319
784
|
return unsupportedSyntax(language, node.type, nodeLocation(node, filename, source));
|
|
320
785
|
}
|
|
786
|
+
/**
|
|
787
|
+
* Converts exact `throw new DeclaredError(message)`.
|
|
788
|
+
* @param {import("@babel/types").ThrowStatement} node - Babel throw statement.
|
|
789
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
790
|
+
* @param {string} filename - Source filename.
|
|
791
|
+
* @param {string} source - Complete source.
|
|
792
|
+
* @param {JavaScriptConversionContext} context - Typed lexical context.
|
|
793
|
+
* @returns {import("../semantic/types.js").RaiseStatement} Semantic raise.
|
|
794
|
+
*/
|
|
795
|
+
function convertTypedThrow(node, language, filename, source, context) {
|
|
796
|
+
const location = nodeLocation(node, filename, source);
|
|
797
|
+
const argument = node.argument;
|
|
798
|
+
if (!argument || argument.type != "NewExpression" || argument.callee.type != "Identifier" ||
|
|
799
|
+
context.bindings.has(argument.callee.name) || !context.errorNames.has(argument.callee.name) || argument.arguments.length != 1 ||
|
|
800
|
+
argument.arguments[0].type == "SpreadElement" || argument.arguments[0].type == "ArgumentPlaceholder" ||
|
|
801
|
+
argument.typeArguments || argument.typeParameters) {
|
|
802
|
+
return unsupportedSyntax(language, "throw other than exact declared error construction", location);
|
|
803
|
+
}
|
|
804
|
+
const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(argument.callee.name));
|
|
805
|
+
const typeLocation = identifierLocation(argument.callee, filename, source);
|
|
806
|
+
return withParserRanges({
|
|
807
|
+
error: withParserRanges({
|
|
808
|
+
error: withParserRanges({ declarationId: /** @type {string} */ (declaration.id), kind: /** @type {const} */ ("ErrorType") }, { type: typeLocation }),
|
|
809
|
+
kind: /** @type {const} */ ("ErrorConstruction"),
|
|
810
|
+
location: nodeLocation(argument, filename, source),
|
|
811
|
+
message: convertExpression(argument.arguments[0], language, filename, source, context)
|
|
812
|
+
}, { type: typeLocation }),
|
|
813
|
+
kind: /** @type {const} */ ("RaiseStatement"),
|
|
814
|
+
location
|
|
815
|
+
}, { keyword: tokenLocation(node, "throw", node.start ?? 0, argument.start ?? node.end ?? source.length, filename, source) });
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Converts one catch with the canonical `instanceof` guard and exact rethrow.
|
|
819
|
+
* @param {import("@babel/types").TryStatement} node - Babel try statement.
|
|
820
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
821
|
+
* @param {string} filename - Source filename.
|
|
822
|
+
* @param {string} source - Complete source.
|
|
823
|
+
* @param {boolean} canonicalZeroRequired - Whether scalar output canonicalizes zero.
|
|
824
|
+
* @param {JavaScriptConversionContext} context - Typed lexical context.
|
|
825
|
+
* @returns {import("../semantic/types.js").TryStatement} Semantic exact handler.
|
|
826
|
+
*/
|
|
827
|
+
function convertTypedTry(node, language, filename, source, canonicalZeroRequired, context) {
|
|
828
|
+
const location = nodeLocation(node, filename, source);
|
|
829
|
+
if (node.finalizer || !node.handler || node.handler.param?.type != "Identifier" || node.handler.body.directives.length > 0) {
|
|
830
|
+
return unsupportedSyntax(language, "try without one explicit guarded catch", location);
|
|
831
|
+
}
|
|
832
|
+
const binding = node.handler.param;
|
|
833
|
+
const guard = node.handler.body.body[0];
|
|
834
|
+
if (!guard || guard.type != "IfStatement" || guard.alternate || guard.test.type != "UnaryExpression" ||
|
|
835
|
+
guard.test.operator != "!" || guard.test.argument.type != "BinaryExpression" || guard.test.argument.operator != "instanceof" ||
|
|
836
|
+
guard.test.argument.left.type != "Identifier" || guard.test.argument.left.name != binding.name ||
|
|
837
|
+
guard.test.argument.right.type != "Identifier" || guard.test.argument.right.name == binding.name ||
|
|
838
|
+
context.bindings.has(guard.test.argument.right.name) || !context.errorNames.has(guard.test.argument.right.name) ||
|
|
839
|
+
guard.consequent.type != "BlockStatement" || guard.consequent.body.length != 1 || guard.consequent.directives.length > 0 ||
|
|
840
|
+
guard.consequent.body[0].type != "ThrowStatement" || guard.consequent.body[0].argument?.type != "Identifier" ||
|
|
841
|
+
guard.consequent.body[0].argument.name != binding.name) {
|
|
842
|
+
return unsupportedSyntax(language, "catch without exact instanceof guard and unmatched rethrow", nodeLocation(guard ?? node.handler, filename, source));
|
|
843
|
+
}
|
|
844
|
+
const declaration = /** @type {import("../semantic/types.js").ErrorDeclaration} */ (context.errorNames.get(guard.test.argument.right.name));
|
|
845
|
+
const caughtTypeLocation = identifierLocation(guard.test.argument.right, filename, source);
|
|
846
|
+
const catchType = withParserRanges({
|
|
847
|
+
declarationId: /** @type {string} */ (declaration.id),
|
|
848
|
+
kind: /** @type {const} */ ("ErrorType")
|
|
849
|
+
}, { type: caughtTypeLocation });
|
|
850
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
851
|
+
const catchContext = { ...context, bindings: new Map(context.bindings) };
|
|
852
|
+
catchContext.bindings.set(binding.name, catchType);
|
|
853
|
+
const catchStatements = node.handler.body.body.slice(1);
|
|
854
|
+
return withParserRanges({
|
|
855
|
+
body: convertBlock(node.block, language, filename, source, canonicalZeroRequired, bodyContext),
|
|
856
|
+
catchBinding: withParserRanges({
|
|
857
|
+
kind: /** @type {const} */ ("CatchBinding"),
|
|
858
|
+
location: identifierLocation(binding, filename, source),
|
|
859
|
+
mutable: /** @type {const} */ (false),
|
|
860
|
+
name: binding.name,
|
|
861
|
+
type: catchType
|
|
862
|
+
}, { name: identifierLocation(binding, filename, source) }),
|
|
863
|
+
catchBody: convertBlock(catchStatements, language, filename, source, canonicalZeroRequired, catchContext, nodeLocation(node.handler.body, filename, source)),
|
|
864
|
+
catchType,
|
|
865
|
+
kind: /** @type {const} */ ("TryStatement"),
|
|
866
|
+
location
|
|
867
|
+
}, {
|
|
868
|
+
catch: tokenLocation(node.handler, "catch", node.handler.start ?? 0, binding.start ?? node.handler.end ?? source.length, filename, source),
|
|
869
|
+
guard: nodeLocation(guard, filename, source),
|
|
870
|
+
try: tokenLocation(node, "try", node.start ?? 0, node.block.start ?? node.end ?? source.length, filename, source)
|
|
871
|
+
});
|
|
872
|
+
}
|
|
873
|
+
/**
|
|
874
|
+
* Converts the exact block-bodied `for (const value of list)` profile.
|
|
875
|
+
* @param {import("@babel/types").ForOfStatement} node - Babel for-of statement.
|
|
876
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
877
|
+
* @param {string} filename - Source filename.
|
|
878
|
+
* @param {string} source - Complete source.
|
|
879
|
+
* @param {boolean} canonicalZeroRequired - Whether scalar output canonicalizes zero.
|
|
880
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
881
|
+
* @returns {import("../semantic/types.js").ForEachStatement | import("../semantic/types.js").ForEachMapStatement} Semantic loop.
|
|
882
|
+
*/
|
|
883
|
+
function convertForEach(node, language, filename, source, canonicalZeroRequired, context) {
|
|
884
|
+
const location = nodeLocation(node, filename, source);
|
|
885
|
+
if (node.await)
|
|
886
|
+
return unsupportedSyntax(language, "async for-of", location);
|
|
887
|
+
if (node.left.type != "VariableDeclaration")
|
|
888
|
+
return unsupportedSyntax(language, "for-of assignment binding", nodeLocation(node.left, filename, source));
|
|
889
|
+
if (node.left.kind != "const") {
|
|
890
|
+
return unsupportedSyntax(language, `${node.left.kind} iteration binding`, tokenLocation(node.left, node.left.kind, node.left.start ?? node.start ?? 0, node.left.end ?? node.end ?? source.length, filename, source));
|
|
891
|
+
}
|
|
892
|
+
if (node.left.declarations.length != 1)
|
|
893
|
+
return unsupportedSyntax(language, "multiple iteration bindings", nodeLocation(node.left, filename, source));
|
|
894
|
+
const declarator = node.left.declarations[0];
|
|
895
|
+
if (declarator.id.type == "ArrayPattern") {
|
|
896
|
+
const [key, value] = declarator.id.elements;
|
|
897
|
+
if (declarator.id.elements.length != 2 || !key || !value || key.type != "Identifier" || value.type != "Identifier" ||
|
|
898
|
+
declarator.id.typeAnnotation || key.typeAnnotation || value.typeAnnotation || key.optional || value.optional) {
|
|
899
|
+
return unsupportedSyntax(language, "map iteration binding shape", nodeLocation(declarator.id, filename, source));
|
|
900
|
+
}
|
|
901
|
+
if (declarator.init)
|
|
902
|
+
return unsupportedSyntax(language, "initialized iteration binding", nodeLocation(declarator, filename, source));
|
|
903
|
+
if (node.body.type != "BlockStatement")
|
|
904
|
+
return unsupportedSyntax(language, "for-of without block body", nodeLocation(node.body, filename, source));
|
|
905
|
+
const collectionType = iterationOperandType(knownExpressionType(node.right, context, language, filename, source));
|
|
906
|
+
if (collectionType?.kind == "MapType") {
|
|
907
|
+
return unsupportedSyntax(language, "unordered map iteration", nodeLocation(node.right, filename, source));
|
|
908
|
+
}
|
|
909
|
+
if (!collectionType || collectionType.kind != "OrderedMapType") {
|
|
910
|
+
return missingType(language, "Ordered map iteration collection", nodeLocation(node.right, filename, source));
|
|
911
|
+
}
|
|
912
|
+
const keyLocation = identifierLocation(key, filename, source);
|
|
913
|
+
const valueLocation = identifierLocation(value, filename, source);
|
|
914
|
+
const keyType = iterationBindingType(collectionType.keyType, keyLocation);
|
|
915
|
+
const valueType = iterationBindingType(collectionType.valueType, valueLocation);
|
|
916
|
+
const keyBinding = withParserRanges({
|
|
917
|
+
kind: /** @type {const} */ ("ValueBinding"), location: keyLocation, mutable: /** @type {const} */ (false),
|
|
918
|
+
name: key.name, type: keyType
|
|
919
|
+
}, { name: keyLocation });
|
|
920
|
+
const valueBinding = withParserRanges({
|
|
921
|
+
kind: /** @type {const} */ ("ValueBinding"), location: valueLocation, mutable: /** @type {const} */ (false),
|
|
922
|
+
name: value.name, type: valueType
|
|
923
|
+
}, { name: valueLocation });
|
|
924
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
925
|
+
bodyContext.bindings.set(key.name, keyType);
|
|
926
|
+
bodyContext.bindings.set(value.name, valueType);
|
|
927
|
+
return withParserRanges({
|
|
928
|
+
body: convertBlock(node.body, language, filename, source, canonicalZeroRequired, bodyContext),
|
|
929
|
+
keyBinding,
|
|
930
|
+
kind: /** @type {const} */ ("ForEachMapStatement"),
|
|
931
|
+
location,
|
|
932
|
+
map: convertExpression(node.right, language, filename, source, context),
|
|
933
|
+
valueBinding
|
|
934
|
+
}, {
|
|
935
|
+
operator: tokenLocation(node, "of", node.left.end ?? node.start ?? 0, node.right.start ?? node.end ?? source.length, filename, source)
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
if (declarator.id.type != "Identifier")
|
|
939
|
+
return unsupportedSyntax(language, declarator.id.type, nodeLocation(declarator.id, filename, source));
|
|
940
|
+
if (declarator.init)
|
|
941
|
+
return unsupportedSyntax(language, "initialized iteration binding", nodeLocation(declarator, filename, source));
|
|
942
|
+
if (node.body.type != "BlockStatement")
|
|
943
|
+
return unsupportedSyntax(language, "for-of without block body", nodeLocation(node.body, filename, source));
|
|
944
|
+
const collectionType = iterationOperandType(knownExpressionType(node.right, context, language, filename, source));
|
|
945
|
+
if (collectionType?.kind == "MapType" || collectionType?.kind == "OrderedMapType") {
|
|
946
|
+
return unsupportedSyntax(language, "map iteration without key/value pair binding", nodeLocation(node.right, filename, source));
|
|
947
|
+
}
|
|
948
|
+
if (!collectionType || collectionType.kind != "ListType") {
|
|
949
|
+
return missingType(language, "Iteration collection", nodeLocation(node.right, filename, source));
|
|
950
|
+
}
|
|
951
|
+
const bindingLocation = identifierLocation(declarator.id, filename, source);
|
|
952
|
+
const inferredType = collectionType.elementType;
|
|
953
|
+
const bindingType = language == "typescript" && declarator.id.typeAnnotation
|
|
954
|
+
? convertTypeScriptType(declarator.id.typeAnnotation, `Iteration binding '${declarator.id.name}'`, bindingLocation, filename, source, context.recordNames, context.typeParameters)
|
|
955
|
+
: iterationBindingType(inferredType, bindingLocation);
|
|
956
|
+
const valueBinding = withParserRanges({
|
|
957
|
+
kind: /** @type {const} */ ("ValueBinding"),
|
|
958
|
+
location: bindingLocation,
|
|
959
|
+
mutable: /** @type {const} */ (false),
|
|
960
|
+
name: declarator.id.name,
|
|
961
|
+
type: bindingType
|
|
962
|
+
}, { name: bindingLocation });
|
|
963
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
964
|
+
bodyContext.bindings.set(declarator.id.name, bindingType);
|
|
965
|
+
return withParserRanges({
|
|
966
|
+
body: convertBlock(node.body, language, filename, source, canonicalZeroRequired, bodyContext),
|
|
967
|
+
kind: /** @type {const} */ ("ForEachStatement"),
|
|
968
|
+
list: convertExpression(node.right, language, filename, source, context),
|
|
969
|
+
location,
|
|
970
|
+
valueBinding
|
|
971
|
+
}, {
|
|
972
|
+
operator: tokenLocation(node, "of", node.left.end ?? node.start ?? 0, node.right.start ?? node.end ?? source.length, filename, source)
|
|
973
|
+
});
|
|
974
|
+
}
|
|
321
975
|
/**
|
|
322
976
|
* Converts one Babel block or normalized single-statement body.
|
|
323
977
|
* @param {import("@babel/types").BlockStatement | import("@babel/types").Statement[]} input - Parser block or statements.
|
|
@@ -325,20 +979,31 @@ function convertStatement(node, language, filename, source, canonicalZeroRequire
|
|
|
325
979
|
* @param {string} filename - Source filename.
|
|
326
980
|
* @param {string} source - Complete source.
|
|
327
981
|
* @param {boolean} canonicalZeroRequired - Whether generated scalar output may contain signed zero.
|
|
982
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
328
983
|
* @param {import("../semantic/types.js").SourceLocation} [location] - Location for a statement-array block.
|
|
329
984
|
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
330
985
|
*/
|
|
331
|
-
function convertBlock(input, language, filename, source, canonicalZeroRequired, location) {
|
|
986
|
+
function convertBlock(input, language, filename, source, canonicalZeroRequired, context, location) {
|
|
332
987
|
const statements = Array.isArray(input) ? input : input.body;
|
|
333
988
|
const directives = Array.isArray(input) ? [] : input.directives;
|
|
334
989
|
const blockLocation = location ?? nodeLocation(/** @type {import("@babel/types").BlockStatement} */ (input), filename, source);
|
|
990
|
+
const lexicalValueNames = new Set(context.lexicalValueNames);
|
|
991
|
+
for (const statement of statements) {
|
|
992
|
+
if (statement.type != "VariableDeclaration")
|
|
993
|
+
continue;
|
|
994
|
+
for (const declarator of statement.declarations) {
|
|
995
|
+
if (declarator.id.type == "Identifier")
|
|
996
|
+
lexicalValueNames.add(declarator.id.name);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
const blockContext = { ...context, lexicalValueNames };
|
|
335
1000
|
if (directives.length > 0) {
|
|
336
1001
|
return unsupportedSyntax(language, "directive", nodeLocation(directives[0], filename, source));
|
|
337
1002
|
}
|
|
338
1003
|
return {
|
|
339
1004
|
kind: "Block",
|
|
340
1005
|
location: blockLocation,
|
|
341
|
-
statements: statements.map((statement) => convertStatement(statement, language, filename, source, canonicalZeroRequired))
|
|
1006
|
+
statements: statements.map((statement) => convertStatement(statement, language, filename, source, canonicalZeroRequired, blockContext))
|
|
342
1007
|
};
|
|
343
1008
|
}
|
|
344
1009
|
/**
|
|
@@ -346,35 +1011,112 @@ function convertBlock(input, language, filename, source, canonicalZeroRequired,
|
|
|
346
1011
|
* @param {import("@babel/types").FunctionDeclaration} node - Babel function node.
|
|
347
1012
|
* @param {string} filename - Source filename.
|
|
348
1013
|
* @param {string} source - Complete source.
|
|
349
|
-
* @
|
|
1014
|
+
* @param {string} [ownerId] - Stable declaration identity for type-parameter IDs.
|
|
1015
|
+
* @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[]}} Parsed types.
|
|
350
1016
|
*/
|
|
351
|
-
function jsdocTypes(node, filename, source) {
|
|
1017
|
+
function jsdocTypes(node, filename, source, ownerId) {
|
|
352
1018
|
const comment = node.leadingComments?.find((candidate) => candidate.type == "CommentBlock" && candidate.value.startsWith("*"));
|
|
353
1019
|
if (!comment)
|
|
354
1020
|
missingType("javascript", `Function '${node.id?.name ?? "anonymous"}'`, nodeLocation(node, filename, source));
|
|
355
1021
|
const commentBlock = /** @type {import("@babel/types").CommentBlock} */ (comment);
|
|
356
1022
|
const block = parseComment(`/*${commentBlock.value}*/`)[0];
|
|
357
|
-
const
|
|
1023
|
+
const parameterTags = block.tags.filter((tag) => tag.tag == "param");
|
|
1024
|
+
const returnTags = block.tags.filter((tag) => tag.tag == "returns" || tag.tag == "return");
|
|
1025
|
+
const typeParameters = jsdocTypeParameters(commentBlock, block.tags, ownerId, filename, source);
|
|
1026
|
+
if (new Set(parameterTags.map((tag) => tag.name)).size != parameterTags.length) {
|
|
1027
|
+
const duplicate = parameterTags.find((tag, index) => parameterTags.findIndex((candidate) => candidate.name == tag.name) != index);
|
|
1028
|
+
return unsupportedSyntax("javascript", "duplicate @param annotation", duplicate
|
|
1029
|
+
? commentTagLocation(commentBlock, duplicate, "name", filename, source)
|
|
1030
|
+
: nodeLocation(node, filename, source));
|
|
1031
|
+
}
|
|
1032
|
+
if (returnTags.length > 1) {
|
|
1033
|
+
return unsupportedSyntax("javascript", "duplicate @return annotation", commentTagLocation(commentBlock, returnTags[1], "type", filename, source));
|
|
1034
|
+
}
|
|
1035
|
+
const parameters = new Map(parameterTags.map((tag) => [tag.name, {
|
|
358
1036
|
location: commentTagLocation(commentBlock, tag, "type", filename, source),
|
|
359
1037
|
sourceType: tag.type
|
|
360
1038
|
}]));
|
|
361
|
-
const returnTag =
|
|
1039
|
+
const returnTag = returnTags[0];
|
|
362
1040
|
return {
|
|
363
1041
|
parameters,
|
|
364
|
-
returnType: returnTag ? { location: commentTagLocation(commentBlock, returnTag, "type", filename, source), sourceType: returnTag.type } : undefined
|
|
1042
|
+
returnType: returnTag ? { location: commentTagLocation(commentBlock, returnTag, "type", filename, source), sourceType: returnTag.type } : undefined,
|
|
1043
|
+
...(typeParameters ? { typeParameters } : {})
|
|
365
1044
|
};
|
|
366
1045
|
}
|
|
1046
|
+
/**
|
|
1047
|
+
* Reads exact unbounded invariant `@template Name` declarations.
|
|
1048
|
+
* @param {import("@babel/types").CommentBlock} comment - Parser-owned JSDoc block.
|
|
1049
|
+
* @param {import("comment-parser").Spec[]} tags - Parsed tags.
|
|
1050
|
+
* @param {string | undefined} ownerId - Stable declaration identity.
|
|
1051
|
+
* @param {string} filename - Source filename.
|
|
1052
|
+
* @param {string} source - Complete source.
|
|
1053
|
+
* @returns {import("../semantic/types.js").TypeParameter[] | undefined} Ordered parameters when present.
|
|
1054
|
+
*/
|
|
1055
|
+
function jsdocTypeParameters(comment, tags, ownerId, filename, source) {
|
|
1056
|
+
const malformed = tags.find((tag) => tag.tag.startsWith("template") && tag.tag != "template");
|
|
1057
|
+
if (malformed)
|
|
1058
|
+
return unsupportedSyntax("javascript", "unsupported type parameter variance", commentTagLocation(comment, malformed, "name", filename, source));
|
|
1059
|
+
const templateTags = tags.filter((tag) => tag.tag == "template");
|
|
1060
|
+
if (templateTags.length == 0)
|
|
1061
|
+
return undefined;
|
|
1062
|
+
if (!ownerId)
|
|
1063
|
+
return unsupportedSyntax("javascript", "type parameter outside a declaration", nodeLocation(/** @type {import("@babel/types").Node} */ ( /** @type {unknown} */(comment)), filename, source));
|
|
1064
|
+
return templateTags.map((tag, index) => {
|
|
1065
|
+
const location = commentTagLocation(comment, tag, "name", filename, source);
|
|
1066
|
+
if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/u.test(tag.name) || tag.type || tag.description) {
|
|
1067
|
+
return unsupportedSyntax("javascript", "bounded, defaulted, or malformed type parameter", location);
|
|
1068
|
+
}
|
|
1069
|
+
return withParserRanges({ id: `${ownerId}:type:${index}`, kind: /** @type {const} */ ("TypeParameter"), location, name: tag.name }, { name: location });
|
|
1070
|
+
});
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Reads an optional class-level JSDoc template block.
|
|
1074
|
+
* @param {import("@babel/types").ClassDeclaration} node - Class declaration.
|
|
1075
|
+
* @param {string} ownerId - Record identity.
|
|
1076
|
+
* @param {string} filename - Source filename.
|
|
1077
|
+
* @param {string} source - Complete source.
|
|
1078
|
+
* @returns {import("../semantic/types.js").TypeParameter[] | undefined} Ordered parameters.
|
|
1079
|
+
*/
|
|
1080
|
+
function classJsdocTypeParameters(node, ownerId, filename, source) {
|
|
1081
|
+
const comment = /** @type {import("@babel/types").CommentBlock | undefined} */ (node.leadingComments?.find((candidate) => candidate.type == "CommentBlock" && candidate.value.startsWith("*")));
|
|
1082
|
+
if (!comment)
|
|
1083
|
+
return undefined;
|
|
1084
|
+
const block = parseComment(`/*${comment.value}*/`)[0];
|
|
1085
|
+
return jsdocTypeParameters(comment, block.tags, ownerId, filename, source);
|
|
1086
|
+
}
|
|
367
1087
|
/**
|
|
368
1088
|
* Requires a supported JavaScript JSDoc scalar type spelling.
|
|
369
1089
|
* @param {string | undefined} sourceType - Source-language type.
|
|
370
1090
|
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
371
1091
|
* @param {string} subject - Typed subject.
|
|
372
1092
|
* @param {import("../semantic/types.js").SourceLocation} location - Source location.
|
|
1093
|
+
* @param {string} source - Complete parser input.
|
|
373
1094
|
* @param {import("../semantic/types.js").SourceLocation} [typeLocation] - Exact type token location.
|
|
374
|
-
* @
|
|
1095
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
|
|
1096
|
+
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1097
|
+
* @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
|
|
375
1098
|
*/
|
|
376
|
-
function convertType(sourceType, language, subject, location, typeLocation = location) {
|
|
377
|
-
|
|
1099
|
+
function convertType(sourceType, language, subject, location, source, typeLocation = location, recordNames = new Map(), typeParameters = new Map()) {
|
|
1100
|
+
if (language != "javascript")
|
|
1101
|
+
return requireSourceScalarType(language, sourceType, subject, location, typeLocation);
|
|
1102
|
+
return documentedValueType({ language, location: typeLocation, ownerLocation: location, records: recordNames, source, sourceType, subject, typeParameters });
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Converts one exact JavaScript function return annotation.
|
|
1106
|
+
* @param {string | undefined} sourceType - JSDoc type spelling.
|
|
1107
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
1108
|
+
* @param {string} subject - Typed function return.
|
|
1109
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Function location.
|
|
1110
|
+
* @param {string} source - Complete parser input.
|
|
1111
|
+
* @param {import("../semantic/types.js").SourceLocation} [typeLocation] - Exact annotation location.
|
|
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 {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1114
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
|
|
1115
|
+
*/
|
|
1116
|
+
function convertReturnType(sourceType, language, subject, location, source, typeLocation = location, recordNames = new Map(), typeParameters = new Map()) {
|
|
1117
|
+
if (sourceType == "void")
|
|
1118
|
+
return requireSourceReturnType(language, sourceType, subject, location, typeLocation);
|
|
1119
|
+
return convertType(sourceType, language, subject, location, source, typeLocation, recordNames, typeParameters);
|
|
378
1120
|
}
|
|
379
1121
|
/**
|
|
380
1122
|
* Converts one exact TypeScript scalar keyword annotation.
|
|
@@ -383,35 +1125,142 @@ function convertType(sourceType, language, subject, location, typeLocation = loc
|
|
|
383
1125
|
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration location.
|
|
384
1126
|
* @param {string} filename - Source filename.
|
|
385
1127
|
* @param {string} source - Complete source.
|
|
386
|
-
* @
|
|
1128
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
|
|
1129
|
+
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1130
|
+
* @returns {import("../semantic/types.js").SemanticValueType} Semantic type.
|
|
387
1131
|
*/
|
|
388
|
-
function convertTypeScriptType(annotation, subject, ownerLocation, filename, source) {
|
|
1132
|
+
function convertTypeScriptType(annotation, subject, ownerLocation, filename, source, recordNames = new Map(), typeParameters = new Map()) {
|
|
389
1133
|
if (!annotation)
|
|
390
1134
|
return missingType("typescript", subject, ownerLocation);
|
|
391
1135
|
if (annotation.type != "TSTypeAnnotation") {
|
|
392
1136
|
return unsupportedSyntax("typescript", "unsupported scalar type", nodeLocation(annotation, filename, source));
|
|
393
1137
|
}
|
|
1138
|
+
return convertTypeScriptValueTypeNode(annotation.typeAnnotation, subject, ownerLocation, filename, source, recordNames, typeParameters);
|
|
1139
|
+
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Converts one bounded recursive TypeScript value-type tree.
|
|
1142
|
+
* @param {import("@babel/types").TSType} typeNode - Parser-owned type node.
|
|
1143
|
+
* @param {string} subject - Typed subject.
|
|
1144
|
+
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration.
|
|
1145
|
+
* @param {string} filename - Source filename.
|
|
1146
|
+
* @param {string} source - Complete source.
|
|
1147
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
|
|
1148
|
+
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1149
|
+
* @returns {import("../semantic/types.js").SemanticValueType} Semantic value type.
|
|
1150
|
+
*/
|
|
1151
|
+
function convertTypeScriptValueTypeNode(typeNode, subject, ownerLocation, filename, source, recordNames = new Map(), typeParameters = new Map()) {
|
|
1152
|
+
const sourceType = typeNode.type == "TSNumberKeyword" ? "number" :
|
|
1153
|
+
typeNode.type == "TSBooleanKeyword" ? "boolean" : typeNode.type == "TSStringKeyword" ? "string" : undefined;
|
|
1154
|
+
if (sourceType) {
|
|
1155
|
+
return requireSourceScalarType("typescript", sourceType, subject, ownerLocation, nodeLocation(typeNode, filename, source));
|
|
1156
|
+
}
|
|
1157
|
+
if (typeNode.type == "TSTypeReference" && typeNode.typeName.type == "Identifier" && !typeNode.typeParameters &&
|
|
1158
|
+
typeParameters.has(typeNode.typeName.name)) {
|
|
1159
|
+
const parameter = /** @type {import("../semantic/types.js").TypeParameter} */ (typeParameters.get(typeNode.typeName.name));
|
|
1160
|
+
return typeVariable(/** @type {string} */ (parameter.id), nodeLocation(typeNode, filename, source));
|
|
1161
|
+
}
|
|
1162
|
+
if (typeNode.type == "TSTypeReference" && typeNode.typeName.type == "Identifier" &&
|
|
1163
|
+
recordNames.has(typeNode.typeName.name)) {
|
|
1164
|
+
const declaration = /** @type {import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration} */ (recordNames.get(typeNode.typeName.name));
|
|
1165
|
+
if (declaration.kind == "EffectResourceDeclaration") {
|
|
1166
|
+
if (typeNode.typeParameters)
|
|
1167
|
+
return unsupportedSyntax("typescript", "generic owned resource type", nodeLocation(typeNode, filename, source));
|
|
1168
|
+
return ownedResourceType(declaration.id, nodeLocation(typeNode.typeName, filename, source));
|
|
1169
|
+
}
|
|
1170
|
+
if (declaration.kind == "ClassDeclaration") {
|
|
1171
|
+
if (typeNode.typeParameters)
|
|
1172
|
+
return unsupportedSyntax("typescript", "generic reference class type", nodeLocation(typeNode, filename, source));
|
|
1173
|
+
const location = nodeLocation(typeNode.typeName, filename, source);
|
|
1174
|
+
return declaration.ownership?.kind == "ownedResource"
|
|
1175
|
+
? ownedReferenceType(/** @type {string} */ (declaration.id), location)
|
|
1176
|
+
: referenceType(/** @type {string} */ (declaration.id), location);
|
|
1177
|
+
}
|
|
1178
|
+
const arguments_ = typeNode.typeParameters?.params.map((parameter) => convertTypeScriptValueTypeNode(parameter, subject, ownerLocation, filename, source, recordNames, typeParameters));
|
|
1179
|
+
return recordType(/** @type {string} */ (declaration.id), nodeLocation(typeNode.typeName, filename, source), arguments_);
|
|
1180
|
+
}
|
|
1181
|
+
if (typeNode.type == "TSUnionType") {
|
|
1182
|
+
if (typeNode.types.length != 2 || typeNode.types[1].type != "TSNullKeyword") {
|
|
1183
|
+
return unsupportedSyntax("typescript", typeNode.types.some((member) => member.type == "TSNullKeyword")
|
|
1184
|
+
? "arbitrary union type"
|
|
1185
|
+
: "unsupported collection or scalar type", nodeLocation(typeNode, filename, source));
|
|
1186
|
+
}
|
|
1187
|
+
const valueNode = typeNode.types[0];
|
|
1188
|
+
return optionalType(convertTypeScriptValueTypeNode(valueNode, subject, ownerLocation, filename, source, recordNames, typeParameters), nodeLocation(typeNode, filename, source), nodeLocation(valueNode, filename, source));
|
|
1189
|
+
}
|
|
1190
|
+
if (typeNode.type == "TSTypeOperator" && typeNode.operator == "readonly" && typeNode.typeAnnotation.type == "TSArrayType") {
|
|
1191
|
+
const elementNode = typeNode.typeAnnotation.elementType;
|
|
1192
|
+
return listType(convertTypeScriptValueTypeNode(elementNode, subject, ownerLocation, filename, source, recordNames, typeParameters), nodeLocation(typeNode, filename, source), nodeLocation(elementNode, filename, source));
|
|
1193
|
+
}
|
|
1194
|
+
if (typeNode.type == "TSTypeReference" && typeNode.typeName.type == "Identifier" &&
|
|
1195
|
+
["ReadonlyArray", "ReadonlyMap"].includes(typeNode.typeName.name)) {
|
|
1196
|
+
const parameters = typeNode.typeParameters?.params ?? [];
|
|
1197
|
+
if (typeNode.typeName.name == "ReadonlyArray" && parameters.length == 1) {
|
|
1198
|
+
return listType(convertTypeScriptValueTypeNode(parameters[0], subject, ownerLocation, filename, source, recordNames, typeParameters), nodeLocation(typeNode, filename, source), nodeLocation(parameters[0], filename, source));
|
|
1199
|
+
}
|
|
1200
|
+
if (typeNode.typeName.name == "ReadonlyMap" && parameters.length == 2) {
|
|
1201
|
+
const keyType = convertTypeScriptValueTypeNode(parameters[0], subject, ownerLocation, filename, source, recordNames, typeParameters);
|
|
1202
|
+
if (keyType.kind != "TypeReference") {
|
|
1203
|
+
return unsupportedSyntax("typescript", "map key type other than string", nodeLocation(parameters[0], filename, source));
|
|
1204
|
+
}
|
|
1205
|
+
return mapType(keyType, convertTypeScriptValueTypeNode(parameters[1], subject, ownerLocation, filename, source, recordNames, typeParameters), nodeLocation(typeNode, filename, source), nodeLocation(parameters[0], filename, source), nodeLocation(parameters[1], filename, source));
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
return unsupportedSyntax("typescript", "unsupported collection or scalar type", nodeLocation(typeNode, filename, source));
|
|
1209
|
+
}
|
|
1210
|
+
/**
|
|
1211
|
+
* Converts one exact TypeScript function return annotation.
|
|
1212
|
+
* @param {import("@babel/types").TypeAnnotation | import("@babel/types").TSTypeAnnotation | import("@babel/types").Noop | null | undefined} annotation - Return annotation.
|
|
1213
|
+
* @param {string} subject - Typed function return.
|
|
1214
|
+
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Function location.
|
|
1215
|
+
* @param {string} filename - Source filename.
|
|
1216
|
+
* @param {string} source - Complete source.
|
|
1217
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} [recordNames] - Nominal declarations by source name.
|
|
1218
|
+
* @param {Map<string, import("../semantic/types.js").TypeParameter>} [typeParameters] - Declaration-scoped parameters.
|
|
1219
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic return type.
|
|
1220
|
+
*/
|
|
1221
|
+
function convertTypeScriptReturnType(annotation, subject, ownerLocation, filename, source, recordNames = new Map(), typeParameters = new Map()) {
|
|
1222
|
+
if (!annotation)
|
|
1223
|
+
return requireSourceReturnType("typescript", undefined, subject, ownerLocation);
|
|
1224
|
+
if (annotation.type != "TSTypeAnnotation") {
|
|
1225
|
+
return unsupportedSyntax("typescript", "unsupported return type", nodeLocation(annotation, filename, source));
|
|
1226
|
+
}
|
|
394
1227
|
const typeNode = annotation.typeAnnotation;
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
: typeNode.type == "TSBooleanKeyword"
|
|
398
|
-
? "boolean"
|
|
399
|
-
: typeNode.type == "TSStringKeyword" ? "string" : undefined;
|
|
400
|
-
if (!sourceType) {
|
|
401
|
-
return unsupportedSyntax("typescript", "unsupported scalar type", nodeLocation(typeNode, filename, source));
|
|
1228
|
+
if (typeNode.type == "TSVoidKeyword") {
|
|
1229
|
+
return requireSourceReturnType("typescript", "void", subject, ownerLocation, nodeLocation(typeNode, filename, source));
|
|
402
1230
|
}
|
|
403
|
-
return
|
|
1231
|
+
return convertTypeScriptValueTypeNode(typeNode, subject, ownerLocation, filename, source, recordNames, typeParameters);
|
|
1232
|
+
}
|
|
1233
|
+
/**
|
|
1234
|
+
* Converts one native unbounded invariant TypeScript parameter list.
|
|
1235
|
+
* @param {import("@babel/types").TSTypeParameterDeclaration | null | undefined} declaration - Parser-owned list.
|
|
1236
|
+
* @param {string} ownerId - Stable owning declaration identity.
|
|
1237
|
+
* @param {string} filename - Source filename.
|
|
1238
|
+
* @param {string} source - Complete source.
|
|
1239
|
+
* @returns {import("../semantic/types.js").TypeParameter[] | undefined} Semantic parameters.
|
|
1240
|
+
*/
|
|
1241
|
+
function typeScriptTypeParameters(declaration, ownerId, filename, source) {
|
|
1242
|
+
if (!declaration)
|
|
1243
|
+
return undefined;
|
|
1244
|
+
return declaration.params.map((parameter, index) => {
|
|
1245
|
+
const location = nodeLocation(parameter, filename, source);
|
|
1246
|
+
if (parameter.constraint || parameter.default || Reflect.get(parameter, "in") || Reflect.get(parameter, "out") ||
|
|
1247
|
+
Reflect.get(parameter, "const") || typeof parameter.name != "string") {
|
|
1248
|
+
return unsupportedSyntax("typescript", "bounded, defaulted, variant, or const type parameter", location);
|
|
1249
|
+
}
|
|
1250
|
+
return withParserRanges({ id: `${ownerId}:type:${index}`, kind: /** @type {const} */ ("TypeParameter"), location, name: parameter.name }, { name: location });
|
|
1251
|
+
});
|
|
404
1252
|
}
|
|
405
1253
|
/**
|
|
406
|
-
* Converts a supported function
|
|
1254
|
+
* Converts a supported function signature before any body expressions.
|
|
407
1255
|
* @param {import("@babel/types").FunctionDeclaration} node - Babel function.
|
|
408
1256
|
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
409
1257
|
* @param {string} filename - Source filename.
|
|
410
1258
|
* @param {string} source - Complete source.
|
|
411
|
-
* @param {
|
|
412
|
-
* @
|
|
1259
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by source name.
|
|
1260
|
+
* @param {string} ownerId - Stable function identity.
|
|
1261
|
+
* @returns {JavaScriptFunctionSignature} Semantic function signature.
|
|
413
1262
|
*/
|
|
414
|
-
function
|
|
1263
|
+
function convertFunctionSignature(node, language, filename, source, recordNames, ownerId) {
|
|
415
1264
|
const location = nodeLocation(node, filename, source);
|
|
416
1265
|
if (!node.id)
|
|
417
1266
|
return unsupportedSyntax(language, "anonymous function", location);
|
|
@@ -419,15 +1268,22 @@ function convertFunction(node, language, filename, source, canonicalZeroRequired
|
|
|
419
1268
|
return unsupportedSyntax(language, "async function", location);
|
|
420
1269
|
if (node.generator)
|
|
421
1270
|
return unsupportedSyntax(language, "generator function", location);
|
|
422
|
-
const
|
|
1271
|
+
const nativeTypeParameters = language == "typescript"
|
|
1272
|
+
? typeScriptTypeParameters(/** @type {import("@babel/types").TSTypeParameterDeclaration | null | undefined} */ (node.typeParameters), ownerId, filename, source)
|
|
1273
|
+
: node.typeParameters ? unsupportedSyntax(language, "native generic function", nodeLocation(node.typeParameters, filename, source)) : undefined;
|
|
1274
|
+
const documentedTypes = language == "javascript" ? jsdocTypes(node, filename, source, ownerId) : undefined;
|
|
1275
|
+
const typeParameters_ = nativeTypeParameters ?? documentedTypes?.typeParameters;
|
|
1276
|
+
const typeParameterNames = new Map((typeParameters_ ?? []).map((parameter) => [parameter.name, parameter]));
|
|
423
1277
|
const parameters = node.params.map((parameter) => {
|
|
424
1278
|
const parameterLocation = nodeLocation(parameter, filename, source);
|
|
425
1279
|
if (parameter.type != "Identifier")
|
|
426
1280
|
return unsupportedSyntax(language, parameter.type, parameterLocation);
|
|
1281
|
+
if (parameter.optional)
|
|
1282
|
+
return unsupportedSyntax(language, "optional parameter", parameterLocation);
|
|
427
1283
|
const documentedType = documentedTypes?.parameters.get(parameter.name);
|
|
428
1284
|
const type = language == "javascript"
|
|
429
|
-
? convertType(documentedType?.sourceType, language, `Parameter '${parameter.name}'`, parameterLocation, documentedType?.location)
|
|
430
|
-
: convertTypeScriptType(parameter.typeAnnotation, `Parameter '${parameter.name}'`, parameterLocation, filename, source);
|
|
1285
|
+
? convertType(documentedType?.sourceType, language, `Parameter '${parameter.name}'`, parameterLocation, source, documentedType?.location, recordNames, typeParameterNames)
|
|
1286
|
+
: convertTypeScriptType(parameter.typeAnnotation, `Parameter '${parameter.name}'`, parameterLocation, filename, source, recordNames, typeParameterNames);
|
|
431
1287
|
return withParserRanges({
|
|
432
1288
|
kind: /** @type {const} */ ("Parameter"),
|
|
433
1289
|
location: parameterLocation,
|
|
@@ -435,19 +1291,448 @@ function convertFunction(node, language, filename, source, canonicalZeroRequired
|
|
|
435
1291
|
type
|
|
436
1292
|
}, { name: identifierLocation(parameter, filename, source) });
|
|
437
1293
|
});
|
|
1294
|
+
const extraDocumentedParameter = documentedTypes && [...documentedTypes.parameters.keys()]
|
|
1295
|
+
.find((name) => !node.params.some((parameter) => parameter.type == "Identifier" && parameter.name == name));
|
|
1296
|
+
if (extraDocumentedParameter)
|
|
1297
|
+
return unsupportedSyntax(language, `annotation for unknown parameter '${extraDocumentedParameter}'`, location);
|
|
438
1298
|
const returnAnnotation = node.returnType;
|
|
439
1299
|
const returnType = language == "javascript"
|
|
440
|
-
?
|
|
441
|
-
:
|
|
442
|
-
|
|
443
|
-
return withParserRanges({
|
|
444
|
-
body,
|
|
445
|
-
kind: "FunctionDeclaration",
|
|
1300
|
+
? convertReturnType(documentedTypes?.returnType?.sourceType, language, `Function '${node.id.name}' return`, location, source, documentedTypes?.returnType?.location, recordNames, typeParameterNames)
|
|
1301
|
+
: convertTypeScriptReturnType(returnAnnotation, `Function '${node.id.name}' return`, location, filename, source, recordNames, typeParameterNames);
|
|
1302
|
+
return {
|
|
446
1303
|
location,
|
|
447
1304
|
name: node.id.name,
|
|
1305
|
+
nameLocation: identifierLocation(node.id, filename, source),
|
|
448
1306
|
parameters,
|
|
449
|
-
returnType
|
|
450
|
-
|
|
1307
|
+
returnType,
|
|
1308
|
+
...(typeParameters_ ? { typeParameters: typeParameters_ } : {})
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
/**
|
|
1312
|
+
* Converts a supported function body using all already-proved signatures.
|
|
1313
|
+
* @param {import("@babel/types").FunctionDeclaration} node - Babel function.
|
|
1314
|
+
* @param {JavaScriptFunctionSignature} signature - Converted signature.
|
|
1315
|
+
* @param {Map<string, JavaScriptFunctionSignature>} functions - Module signatures.
|
|
1316
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by name.
|
|
1317
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} valueRecordNames - Nominal declarations available in value positions.
|
|
1318
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Record declarations by identity.
|
|
1319
|
+
* @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Reference classes by identity.
|
|
1320
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Error declarations by source name.
|
|
1321
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Error declarations by identity.
|
|
1322
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
1323
|
+
* @param {string} filename - Source filename.
|
|
1324
|
+
* @param {string} source - Complete source.
|
|
1325
|
+
* @param {boolean} canonicalZeroRequired - Whether generated scalar output may contain signed zero.
|
|
1326
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
1327
|
+
*/
|
|
1328
|
+
function convertFunction(node, signature, functions, recordNames, valueRecordNames, records, classes, errorNames, errors, language, filename, source, canonicalZeroRequired) {
|
|
1329
|
+
const context = {
|
|
1330
|
+
bindings: new Map(signature.parameters.map((parameter) => [parameter.name, parameter.type])),
|
|
1331
|
+
classes,
|
|
1332
|
+
errorNames,
|
|
1333
|
+
errors,
|
|
1334
|
+
functions,
|
|
1335
|
+
orderedMapDeclarations: orderedMapDeclarationsFor(node.body),
|
|
1336
|
+
recordNames,
|
|
1337
|
+
records,
|
|
1338
|
+
returnType: signature.returnType,
|
|
1339
|
+
typeParameters: new Map((signature.typeParameters ?? []).map((parameter) => [parameter.name, parameter])),
|
|
1340
|
+
valueRecordNames
|
|
1341
|
+
};
|
|
1342
|
+
const body = convertBlock(node.body, language, filename, source, canonicalZeroRequired, context);
|
|
1343
|
+
return withParserRanges({
|
|
1344
|
+
body,
|
|
1345
|
+
kind: "FunctionDeclaration",
|
|
1346
|
+
location: signature.location,
|
|
1347
|
+
name: signature.name,
|
|
1348
|
+
parameters: signature.parameters,
|
|
1349
|
+
returnType: signature.returnType,
|
|
1350
|
+
...(signature.typeParameters ? { typeParameters: signature.typeParameters } : {})
|
|
1351
|
+
}, { name: signature.nameLocation });
|
|
1352
|
+
}
|
|
1353
|
+
/**
|
|
1354
|
+
* Resolves parser-owned pair loops to exact declarations inside one lexical owner.
|
|
1355
|
+
* Ambiguous same-name declarations produce no evidence and fail during loop conversion.
|
|
1356
|
+
* @param {unknown} value - Function body or entry-point subtree.
|
|
1357
|
+
* @returns {Set<object>} Exact pair-iterated parser declarations.
|
|
1358
|
+
*/
|
|
1359
|
+
function orderedMapDeclarationsFor(value) {
|
|
1360
|
+
/** @type {{declaration: object, name: string, offset: number}[]} */
|
|
1361
|
+
const declarations = [];
|
|
1362
|
+
/** @type {{name: string, offset: number}[]} */
|
|
1363
|
+
const receivers = [];
|
|
1364
|
+
const seen = new WeakSet();
|
|
1365
|
+
/**
|
|
1366
|
+
* Visits one parser candidate.
|
|
1367
|
+
* @param {unknown} candidate - Parser candidate.
|
|
1368
|
+
*/
|
|
1369
|
+
const visit = (candidate) => {
|
|
1370
|
+
if (!candidate || typeof candidate != "object" || seen.has(candidate))
|
|
1371
|
+
return;
|
|
1372
|
+
seen.add(candidate);
|
|
1373
|
+
const type = Reflect.get(candidate, "type");
|
|
1374
|
+
if (type == "FunctionDeclaration" || type == "ClassDeclaration")
|
|
1375
|
+
return;
|
|
1376
|
+
if (type == "VariableDeclarator") {
|
|
1377
|
+
const identifier = Reflect.get(candidate, "id");
|
|
1378
|
+
if (Reflect.get(identifier, "type") == "Identifier")
|
|
1379
|
+
declarations.push({
|
|
1380
|
+
declaration: candidate,
|
|
1381
|
+
name: Reflect.get(identifier, "name"),
|
|
1382
|
+
offset: Reflect.get(candidate, "start")
|
|
1383
|
+
});
|
|
1384
|
+
}
|
|
1385
|
+
else if (type == "ForOfStatement") {
|
|
1386
|
+
const left = Reflect.get(candidate, "left");
|
|
1387
|
+
const right = Reflect.get(candidate, "right");
|
|
1388
|
+
const loopDeclarations = left && typeof left == "object" ? Reflect.get(left, "declarations") : undefined;
|
|
1389
|
+
const pattern = Array.isArray(loopDeclarations) && loopDeclarations.length == 1 ? Reflect.get(loopDeclarations[0], "id") : undefined;
|
|
1390
|
+
const elements = pattern && typeof pattern == "object" ? Reflect.get(pattern, "elements") : undefined;
|
|
1391
|
+
if (Reflect.get(left, "kind") == "const" && Reflect.get(pattern, "type") == "ArrayPattern" &&
|
|
1392
|
+
Array.isArray(elements) && elements.length == 2 && elements.every((element) => Reflect.get(element, "type") == "Identifier") &&
|
|
1393
|
+
Reflect.get(right, "type") == "Identifier")
|
|
1394
|
+
receivers.push({
|
|
1395
|
+
name: Reflect.get(right, "name"),
|
|
1396
|
+
offset: Reflect.get(candidate, "start")
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
for (const [key, child] of Object.entries(candidate)) {
|
|
1400
|
+
if (["extra", "innerComments", "leadingComments", "loc", "trailingComments"].includes(key))
|
|
1401
|
+
continue;
|
|
1402
|
+
if (Array.isArray(child)) {
|
|
1403
|
+
for (const item of child)
|
|
1404
|
+
visit(item);
|
|
1405
|
+
}
|
|
1406
|
+
else
|
|
1407
|
+
visit(child);
|
|
1408
|
+
}
|
|
1409
|
+
};
|
|
1410
|
+
visit(value);
|
|
1411
|
+
const selected = new Set();
|
|
1412
|
+
for (const receiver of receivers) {
|
|
1413
|
+
const matches = declarations.filter(({ name, offset }) => name == receiver.name && offset < receiver.offset);
|
|
1414
|
+
if (matches.length == 1)
|
|
1415
|
+
selected.add(matches[0].declaration);
|
|
1416
|
+
}
|
|
1417
|
+
return selected;
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Converts one exact empty native Error subclass.
|
|
1421
|
+
* @param {import("@babel/types").ClassDeclaration} node - Babel class declaration.
|
|
1422
|
+
* @param {import("../semantic/types.js").ErrorDeclaration} declaration - Predeclared semantic error.
|
|
1423
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
1424
|
+
* @param {string} filename - Source filename.
|
|
1425
|
+
* @param {string} source - Complete source.
|
|
1426
|
+
* @returns {import("../semantic/types.js").ErrorDeclaration} Semantic error declaration.
|
|
1427
|
+
*/
|
|
1428
|
+
function convertJavaScriptError(node, declaration, language, filename, source) {
|
|
1429
|
+
const location = nodeLocation(node, filename, source);
|
|
1430
|
+
if (!node.id || node.superClass?.type != "Identifier" || node.superClass.name != "Error" ||
|
|
1431
|
+
node.body.body.length != 0 || node.decorators?.length || node.typeParameters || node.superTypeParameters ||
|
|
1432
|
+
Reflect.get(node, "abstract") || Reflect.get(node, "declare") || Reflect.get(node, "implements")?.length) {
|
|
1433
|
+
return unsupportedSyntax(language, "noncanonical typed error declaration", location);
|
|
1434
|
+
}
|
|
1435
|
+
return withParserRanges(declaration, {
|
|
1436
|
+
name: identifierLocation(node.id, filename, source),
|
|
1437
|
+
type: identifierLocation(node.superClass, filename, source)
|
|
1438
|
+
});
|
|
1439
|
+
}
|
|
1440
|
+
/**
|
|
1441
|
+
* Predeclares the bounded native private-field reference-class profile and all callable signatures.
|
|
1442
|
+
* @param {import("@babel/types").ClassDeclaration} node - Parser class.
|
|
1443
|
+
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Predeclared class identity.
|
|
1444
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Nominal types by name.
|
|
1445
|
+
* @param {"javascript" | "typescript"} language - Source language.
|
|
1446
|
+
* @param {string} filename - Source filename.
|
|
1447
|
+
* @param {string} source - Complete source.
|
|
1448
|
+
* @returns {import("../semantic/types.js").ClassDeclaration} Semantic class.
|
|
1449
|
+
*/
|
|
1450
|
+
function predeclareReferenceClass(node, declaration, nominalNames, language, filename, source) {
|
|
1451
|
+
const location = nodeLocation(node, filename, source);
|
|
1452
|
+
if (!node.id || node.superClass || node.decorators?.length || node.typeParameters || node.superTypeParameters ||
|
|
1453
|
+
Reflect.get(node, "abstract") || Reflect.get(node, "declare") || Reflect.get(node, "implements")?.length) {
|
|
1454
|
+
return unsupportedSyntax(language, "reference class inheritance, generics, decoration, or modifier", location);
|
|
1455
|
+
}
|
|
1456
|
+
const constructorNodes = /** @type {import("@babel/types").ClassMethod[]} */ (node.body.body.filter((member) => member.type == "ClassMethod" && member.kind == "constructor"));
|
|
1457
|
+
const fieldNodes = node.body.body.filter((member) => member.type == "ClassProperty" || member.type == "ClassPrivateProperty");
|
|
1458
|
+
const methodNodes = /** @type {import("@babel/types").ClassMethod[]} */ (node.body.body.filter((member) => member.type == "ClassMethod" && member.kind == "method"));
|
|
1459
|
+
if (constructorNodes.length != 1 || fieldNodes.length == 0 ||
|
|
1460
|
+
fieldNodes.length + methodNodes.length + constructorNodes.length != node.body.body.length) {
|
|
1461
|
+
return unsupportedSyntax(language, "reference class requires private fields, one constructor, and ordinary methods", location);
|
|
1462
|
+
}
|
|
1463
|
+
declaration.fields = fieldNodes.map((member, index) => {
|
|
1464
|
+
const fieldLocation = nodeLocation(member, filename, source);
|
|
1465
|
+
let name;
|
|
1466
|
+
let nameLocation;
|
|
1467
|
+
let type;
|
|
1468
|
+
if (language == "typescript") {
|
|
1469
|
+
if (member.type != "ClassProperty" || member.key.type != "Identifier" || member.computed || member.static ||
|
|
1470
|
+
member.accessibility != "private" || member.readonly || member.value || member.optional || member.decorators?.length ||
|
|
1471
|
+
Reflect.get(member, "abstract") || Reflect.get(member, "declare")) {
|
|
1472
|
+
return unsupportedSyntax(language, "noncanonical private instance field", fieldLocation);
|
|
1473
|
+
}
|
|
1474
|
+
name = member.key.name;
|
|
1475
|
+
nameLocation = identifierLocation(member.key, filename, source);
|
|
1476
|
+
type = convertTypeScriptType(member.typeAnnotation, `Private field '${name}'`, fieldLocation, filename, source, nominalNames);
|
|
1477
|
+
}
|
|
1478
|
+
else {
|
|
1479
|
+
if (member.type != "ClassPrivateProperty" || member.key.type != "PrivateName" || member.static || member.value ||
|
|
1480
|
+
member.decorators?.length) {
|
|
1481
|
+
return unsupportedSyntax(language, "noncanonical private instance field", fieldLocation);
|
|
1482
|
+
}
|
|
1483
|
+
name = member.key.id.name;
|
|
1484
|
+
nameLocation = identifierLocation(member.key.id, filename, source);
|
|
1485
|
+
const comment = member.leadingComments?.at(-1);
|
|
1486
|
+
const gap = comment ? source.slice(comment.end ?? 0, member.start ?? 0) : "";
|
|
1487
|
+
const block = comment?.type == "CommentBlock" && comment.value.startsWith("*") && /^\s*$/u.test(gap)
|
|
1488
|
+
? parseComment(`/*${comment.value}*/`)[0] : undefined;
|
|
1489
|
+
const tags = block?.tags.filter((tag) => tag.tag == "type") ?? [];
|
|
1490
|
+
if (!comment || tags.length != 1 || tags[0].name || tags[0].description) {
|
|
1491
|
+
return missingType(language, `Private field '${name}'`, fieldLocation);
|
|
1492
|
+
}
|
|
1493
|
+
type = convertType(tags[0].type, language, `Private field '${name}'`, fieldLocation, source, commentTagLocation(/** @type {import("@babel/types").CommentBlock} */ (comment), tags[0], "type", filename, source), nominalNames);
|
|
1494
|
+
}
|
|
1495
|
+
return withParserRanges({ id: `${declaration.id}:field:${index}`, kind: /** @type {const} */ ("PrivateField"),
|
|
1496
|
+
location: fieldLocation, name, type }, { name: nameLocation });
|
|
1497
|
+
});
|
|
1498
|
+
const ownedFields = declaration.fields.filter(({ type }) => type.kind == "OwnedResourceType");
|
|
1499
|
+
if (ownedFields.length == 1) {
|
|
1500
|
+
const ownedField = /** @type {import("../semantic/types.js").PrivateField & {type: import("../semantic/types.js").OwnedResourceType}} */ (ownedFields[0]);
|
|
1501
|
+
declaration.ownership = { fieldId: /** @type {string} */ (ownedField.id), kind: "ownedResource", resourceId: ownedField.type.resourceId };
|
|
1502
|
+
}
|
|
1503
|
+
const constructorNode = /** @type {import("@babel/types").ClassMethod} */ (constructorNodes[0]);
|
|
1504
|
+
const constructorSignature = convertClassCallableSignature(constructorNode, declaration, nominalNames, language, filename, source, true);
|
|
1505
|
+
declaration.constructor = withParserRanges({ body: /** @type {import("../semantic/types.js").Block} */ ({}),
|
|
1506
|
+
id: `${declaration.id}:constructor`, kind: /** @type {const} */ ("ConstructorDeclaration"), location: constructorSignature.location,
|
|
1507
|
+
parameters: constructorSignature.parameters }, { constructor: constructorSignature.nameLocation });
|
|
1508
|
+
declaration.methods = methodNodes.map((methodNode, index) => {
|
|
1509
|
+
const signature = convertClassCallableSignature(methodNode, declaration, nominalNames, language, filename, source, false);
|
|
1510
|
+
return withParserRanges({ body: /** @type {import("../semantic/types.js").Block} */ ({}), id: `${declaration.id}:method:${index}`,
|
|
1511
|
+
kind: /** @type {const} */ ("MethodDeclaration"), location: signature.location, name: signature.name,
|
|
1512
|
+
parameters: signature.parameters, returnType: /** @type {import("../semantic/types.js").SemanticFunctionReturnType} */ (signature.returnType) }, { name: signature.nameLocation });
|
|
1513
|
+
});
|
|
1514
|
+
return withParserRanges(declaration, { name: identifierLocation(node.id, filename, source) });
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Converts one reference class body after every class signature is complete.
|
|
1518
|
+
* @param {import("@babel/types").ClassDeclaration} node - Parser class.
|
|
1519
|
+
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Complete predeclared class signature.
|
|
1520
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Nominal types by name.
|
|
1521
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} valueNames - Nominal constructors by name.
|
|
1522
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration>} records - Records by identity.
|
|
1523
|
+
* @param {Map<string, import("../semantic/types.js").ClassDeclaration>} classes - Classes by identity.
|
|
1524
|
+
* @param {Map<string, JavaScriptFunctionSignature>} functions - Top-level signatures.
|
|
1525
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errorNames - Errors by name.
|
|
1526
|
+
* @param {Map<string, import("../semantic/types.js").ErrorDeclaration>} errors - Errors by identity.
|
|
1527
|
+
* @param {"javascript" | "typescript"} language - Source language.
|
|
1528
|
+
* @param {string} filename - Source filename.
|
|
1529
|
+
* @param {string} source - Complete source.
|
|
1530
|
+
* @param {boolean} canonicalZeroRequired - Whether scalar output canonicalizes zero.
|
|
1531
|
+
* @returns {import("../semantic/types.js").ClassDeclaration} Completed semantic class.
|
|
1532
|
+
*/
|
|
1533
|
+
function convertReferenceClassBodies(node, declaration, nominalNames, valueNames, records, classes, functions, errorNames, errors, language, filename, source, canonicalZeroRequired) {
|
|
1534
|
+
const constructorNode = /** @type {import("@babel/types").ClassMethod} */ (node.body.body.find((member) => member.type == "ClassMethod" && member.kind == "constructor"));
|
|
1535
|
+
const methodNodes = /** @type {import("@babel/types").ClassMethod[]} */ (node.body.body.filter((member) => member.type == "ClassMethod" && member.kind == "method"));
|
|
1536
|
+
const baseContext = { bindings: new Map(), classes, currentClass: declaration, errorNames, errors, functions,
|
|
1537
|
+
recordNames: nominalNames, records, valueRecordNames: valueNames };
|
|
1538
|
+
const constructorContext = { ...baseContext,
|
|
1539
|
+
bindings: new Map(declaration.constructor.parameters.map((parameter) => [parameter.name, parameter.type])),
|
|
1540
|
+
returnType: { kind: /** @type {const} */ ("TypeReference"), name: /** @type {const} */ ("void") } };
|
|
1541
|
+
declaration.constructor.body = convertBlock(constructorNode.body, language, filename, source, canonicalZeroRequired, constructorContext);
|
|
1542
|
+
for (let index = 0; index < methodNodes.length; index += 1) {
|
|
1543
|
+
const method = declaration.methods[index];
|
|
1544
|
+
const context = { ...baseContext, bindings: new Map(method.parameters.map((parameter) => [parameter.name, parameter.type])),
|
|
1545
|
+
returnType: method.returnType };
|
|
1546
|
+
method.body = convertBlock(methodNodes[index].body, language, filename, source, canonicalZeroRequired, context);
|
|
1547
|
+
}
|
|
1548
|
+
return declaration;
|
|
1549
|
+
}
|
|
1550
|
+
/**
|
|
1551
|
+
* Reads one constructor or method signature without admitting overloads or modifiers.
|
|
1552
|
+
* @param {import("@babel/types").ClassMethod} node - Parser method.
|
|
1553
|
+
* @param {import("../semantic/types.js").ClassDeclaration} declaration - Declaring class.
|
|
1554
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} nominalNames - Nominal types.
|
|
1555
|
+
* @param {"javascript" | "typescript"} language - Source language.
|
|
1556
|
+
* @param {string} filename - Source filename.
|
|
1557
|
+
* @param {string} source - Complete source.
|
|
1558
|
+
* @param {boolean} constructor - Whether this is the constructor.
|
|
1559
|
+
* @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}} Signature.
|
|
1560
|
+
*/
|
|
1561
|
+
function convertClassCallableSignature(node, declaration, nominalNames, language, filename, source, constructor) {
|
|
1562
|
+
const location = nodeLocation(node, filename, source);
|
|
1563
|
+
if (node.computed || node.static || node.async || node.generator || node.decorators?.length || node.typeParameters ||
|
|
1564
|
+
node.key.type != "Identifier" || constructor != (node.kind == "constructor") ||
|
|
1565
|
+
language == "typescript" && node.accessibility != null) {
|
|
1566
|
+
return unsupportedSyntax(language, "noncanonical reference class callable", location);
|
|
1567
|
+
}
|
|
1568
|
+
const documented = language == "javascript"
|
|
1569
|
+
? jsdocTypes(/** @type {import("@babel/types").FunctionDeclaration} */ ( /** @type {unknown} */(node)), filename, source)
|
|
1570
|
+
: undefined;
|
|
1571
|
+
if (constructor && (node.returnType || documented?.returnType)) {
|
|
1572
|
+
return unsupportedSyntax(language, "constructor return annotation", location);
|
|
1573
|
+
}
|
|
1574
|
+
const parameters = node.params.map((parameter) => {
|
|
1575
|
+
const parameterLocation = nodeLocation(parameter, filename, source);
|
|
1576
|
+
if (parameter.type != "Identifier" || parameter.optional || parameter.decorators?.length) {
|
|
1577
|
+
return unsupportedSyntax(language, "noncanonical method parameter", parameterLocation);
|
|
1578
|
+
}
|
|
1579
|
+
const documentedType = documented?.parameters.get(parameter.name);
|
|
1580
|
+
const type = language == "typescript"
|
|
1581
|
+
? convertTypeScriptType(parameter.typeAnnotation, `Parameter '${parameter.name}'`, parameterLocation, filename, source, nominalNames)
|
|
1582
|
+
: convertType(documentedType?.sourceType, language, `Parameter '${parameter.name}'`, parameterLocation, source, documentedType?.location, nominalNames);
|
|
1583
|
+
return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: parameterLocation, name: parameter.name, type }, { name: identifierLocation(parameter, filename, source) });
|
|
1584
|
+
});
|
|
1585
|
+
if (documented && documented.parameters.size != parameters.length) {
|
|
1586
|
+
return unsupportedSyntax(language, "method JSDoc parameter mismatch", location);
|
|
1587
|
+
}
|
|
1588
|
+
const name = constructor ? "constructor" : node.key.name;
|
|
1589
|
+
const nameLocation = identifierLocation(node.key, filename, source);
|
|
1590
|
+
if (!constructor && referenceMethodHooks.has(name)) {
|
|
1591
|
+
return unsupportedSyntax(language, `reserved reference method '${name}'`, nameLocation);
|
|
1592
|
+
}
|
|
1593
|
+
return { location, name, nameLocation, parameters, ...(constructor ? {} : { returnType: language == "typescript"
|
|
1594
|
+
? convertTypeScriptReturnType(node.returnType, `Method '${name}' return`, location, filename, source, nominalNames)
|
|
1595
|
+
: convertReturnType(documented?.returnType?.sourceType, language, `Method '${name}' return`, location, source, documented?.returnType?.location, nominalNames) }) };
|
|
1596
|
+
}
|
|
1597
|
+
/**
|
|
1598
|
+
* Converts one exact TypeScript readonly constructor-parameter record profile.
|
|
1599
|
+
* @param {import("@babel/types").ClassDeclaration} node - Class declaration.
|
|
1600
|
+
* @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
|
|
1601
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - All nominal declarations by name.
|
|
1602
|
+
* @param {string} filename - Source filename.
|
|
1603
|
+
* @param {string} source - Complete source.
|
|
1604
|
+
* @returns {import("../semantic/types.js").RecordDeclaration} Semantic record declaration.
|
|
1605
|
+
*/
|
|
1606
|
+
function convertTypeScriptRecord(node, declaration, recordNames, filename, source) {
|
|
1607
|
+
const location = nodeLocation(node, filename, source);
|
|
1608
|
+
const implements_ = Reflect.get(node, "implements");
|
|
1609
|
+
const mixins = Reflect.get(node, "mixins");
|
|
1610
|
+
if (!node.id)
|
|
1611
|
+
return unsupportedSyntax("typescript", "anonymous record class", location);
|
|
1612
|
+
if (node.superClass || (Array.isArray(implements_) && implements_.length) || node.decorators?.length || node.superTypeParameters ||
|
|
1613
|
+
Reflect.get(node, "abstract") || Reflect.get(node, "declare") || (Array.isArray(mixins) && mixins.length)) {
|
|
1614
|
+
return unsupportedSyntax("typescript", "record inheritance, decoration, or modifier", location);
|
|
1615
|
+
}
|
|
1616
|
+
if (node.body.body.length != 1 || node.body.body[0].type != "ClassMethod") {
|
|
1617
|
+
const extra = node.body.body[1] ?? node.body.body[0] ?? node.body;
|
|
1618
|
+
return unsupportedSyntax("typescript", "record class body outside one constructor", nodeLocation(extra, filename, source));
|
|
1619
|
+
}
|
|
1620
|
+
const constructor = node.body.body[0];
|
|
1621
|
+
const typeParameterNames = new Map((declaration.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
|
|
1622
|
+
if (constructor.kind != "constructor" || constructor.computed || constructor.static || constructor.async || constructor.generator ||
|
|
1623
|
+
constructor.key.type != "Identifier" || constructor.key.name != "constructor" || constructor.decorators?.length ||
|
|
1624
|
+
constructor.returnType || constructor.typeParameters || Reflect.get(constructor, "accessibility") ||
|
|
1625
|
+
constructor.body.body.length != 0 || constructor.body.directives.length != 0) {
|
|
1626
|
+
return unsupportedSyntax("typescript", "noncanonical record constructor", nodeLocation(constructor, filename, source));
|
|
1627
|
+
}
|
|
1628
|
+
declaration.fields = constructor.params.map((parameter) => {
|
|
1629
|
+
const fieldLocation = nodeLocation(parameter, filename, source);
|
|
1630
|
+
if (parameter.type != "TSParameterProperty" || parameter.readonly !== true || parameter.accessibility || parameter.override ||
|
|
1631
|
+
parameter.parameter.type != "Identifier" || parameter.parameter.optional || parameter.parameter.decorators?.length) {
|
|
1632
|
+
return unsupportedSyntax("typescript", "record field outside readonly parameter-property profile", fieldLocation);
|
|
1633
|
+
}
|
|
1634
|
+
const identifier = parameter.parameter;
|
|
1635
|
+
const field = {
|
|
1636
|
+
kind: /** @type {const} */ ("RecordField"),
|
|
1637
|
+
location: fieldLocation,
|
|
1638
|
+
name: identifier.name,
|
|
1639
|
+
type: convertTypeScriptType(identifier.typeAnnotation, `Record field '${identifier.name}'`, fieldLocation, filename, source, recordNames, typeParameterNames)
|
|
1640
|
+
};
|
|
1641
|
+
return withParserRanges(field, { name: identifierLocation(identifier, filename, source) });
|
|
1642
|
+
});
|
|
1643
|
+
return withParserRanges(declaration, { name: identifierLocation(node.id, filename, source) });
|
|
1644
|
+
}
|
|
1645
|
+
/**
|
|
1646
|
+
* Converts one exact JSDoc constructor/readonly-assignment/freeze record profile.
|
|
1647
|
+
* @param {import("@babel/types").ClassDeclaration} node - Class declaration.
|
|
1648
|
+
* @param {import("../semantic/types.js").RecordDeclaration} declaration - Predeclared nominal identity.
|
|
1649
|
+
* @param {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} recordNames - Nominal declarations by name.
|
|
1650
|
+
* @param {string} filename - Source filename.
|
|
1651
|
+
* @param {string} source - Complete source.
|
|
1652
|
+
* @returns {import("../semantic/types.js").RecordDeclaration} Semantic record declaration.
|
|
1653
|
+
*/
|
|
1654
|
+
function convertJavaScriptRecord(node, declaration, recordNames, filename, source) {
|
|
1655
|
+
const location = nodeLocation(node, filename, source);
|
|
1656
|
+
const implements_ = Reflect.get(node, "implements");
|
|
1657
|
+
const mixins = Reflect.get(node, "mixins");
|
|
1658
|
+
if (!node.id)
|
|
1659
|
+
return unsupportedSyntax("javascript", "anonymous record class", location);
|
|
1660
|
+
if (node.superClass || node.decorators?.length || node.typeParameters || node.superTypeParameters ||
|
|
1661
|
+
(Array.isArray(implements_) && implements_.length) || (Array.isArray(mixins) && mixins.length)) {
|
|
1662
|
+
return unsupportedSyntax("javascript", "record inheritance or decoration", location);
|
|
1663
|
+
}
|
|
1664
|
+
if (node.body.body.length != 1 || node.body.body[0].type != "ClassMethod") {
|
|
1665
|
+
return unsupportedSyntax("javascript", "record class body outside one constructor", nodeLocation(node.body.body[1] ?? node.body.body[0] ?? node.body, filename, source));
|
|
1666
|
+
}
|
|
1667
|
+
const constructor = node.body.body[0];
|
|
1668
|
+
const typeParameterNames = new Map((declaration.typeParameters ?? []).map((parameter) => [parameter.name, parameter]));
|
|
1669
|
+
if (constructor.kind != "constructor" || constructor.computed || constructor.static || constructor.async || constructor.generator ||
|
|
1670
|
+
constructor.key.type != "Identifier" || constructor.key.name != "constructor" || constructor.decorators?.length ||
|
|
1671
|
+
constructor.returnType || constructor.typeParameters || constructor.body.directives.length) {
|
|
1672
|
+
return unsupportedSyntax("javascript", "noncanonical record constructor", nodeLocation(constructor, filename, source));
|
|
1673
|
+
}
|
|
1674
|
+
const parameters = constructor.params;
|
|
1675
|
+
if (parameters.some((parameter) => parameter.type != "Identifier" || parameter.optional || parameter.decorators?.length)) {
|
|
1676
|
+
const invalid = parameters.find((parameter) => parameter.type != "Identifier" || parameter.optional || parameter.decorators?.length);
|
|
1677
|
+
return unsupportedSyntax("javascript", "noncanonical record constructor parameter", nodeLocation(invalid ?? constructor, filename, source));
|
|
1678
|
+
}
|
|
1679
|
+
const documented = jsdocTypes(/** @type {import("@babel/types").FunctionDeclaration} */ ( /** @type {unknown} */(constructor)), filename, source);
|
|
1680
|
+
if (documented.returnType || documented.parameters.size != parameters.length || constructor.body.body.length != parameters.length + 1) {
|
|
1681
|
+
return unsupportedSyntax("javascript", "incomplete record constructor profile", nodeLocation(constructor, filename, source));
|
|
1682
|
+
}
|
|
1683
|
+
declaration.fields = parameters.map((parameter, index) => {
|
|
1684
|
+
const identifier = /** @type {import("@babel/types").Identifier} */ (parameter);
|
|
1685
|
+
const statement = constructor.body.body[index];
|
|
1686
|
+
const documentedType = documented.parameters.get(identifier.name);
|
|
1687
|
+
if (!documentedType || statement.type != "ExpressionStatement" || statement.expression.type != "AssignmentExpression" ||
|
|
1688
|
+
statement.expression.operator != "=" || statement.expression.left.type != "MemberExpression" || statement.expression.left.computed ||
|
|
1689
|
+
statement.expression.left.object.type != "ThisExpression" || statement.expression.left.property.type != "Identifier" ||
|
|
1690
|
+
statement.expression.left.property.name != identifier.name || statement.expression.right.type != "Identifier" ||
|
|
1691
|
+
statement.expression.right.name != identifier.name) {
|
|
1692
|
+
return unsupportedSyntax("javascript", "record field not initialized exactly once", nodeLocation(statement, filename, source));
|
|
1693
|
+
}
|
|
1694
|
+
const readonlyComment = statement.leadingComments?.at(-1);
|
|
1695
|
+
const gap = readonlyComment ? source.slice(readonlyComment.end ?? 0, statement.start ?? 0) : "";
|
|
1696
|
+
const tags = readonlyComment?.type == "CommentBlock" && readonlyComment.value.startsWith("*")
|
|
1697
|
+
? parseComment(`/*${readonlyComment.value}*/`)[0]?.tags ?? []
|
|
1698
|
+
: [];
|
|
1699
|
+
if (!readonlyComment || !/^\s*$/u.test(gap) || tags.length != 1 || tags[0].tag != "readonly" ||
|
|
1700
|
+
tags[0].name || tags[0].type || tags[0].description) {
|
|
1701
|
+
return unsupportedSyntax("javascript", "record field without exact @readonly annotation", nodeLocation(statement, filename, source));
|
|
1702
|
+
}
|
|
1703
|
+
const field = {
|
|
1704
|
+
kind: /** @type {const} */ ("RecordField"),
|
|
1705
|
+
location: nodeLocation(statement, filename, source),
|
|
1706
|
+
name: identifier.name,
|
|
1707
|
+
type: convertType(documentedType.sourceType, "javascript", `Record field '${identifier.name}'`, nodeLocation(identifier, filename, source), source, documentedType.location, recordNames, typeParameterNames)
|
|
1708
|
+
};
|
|
1709
|
+
return withParserRanges(field, { name: identifierLocation(statement.expression.left.property, filename, source) });
|
|
1710
|
+
});
|
|
1711
|
+
const freeze = constructor.body.body.at(-1);
|
|
1712
|
+
if (!freeze || freeze.type != "ExpressionStatement" || freeze.expression.type != "CallExpression" || freeze.expression.optional ||
|
|
1713
|
+
freeze.expression.arguments.length != 1 || freeze.expression.arguments[0].type != "ThisExpression" ||
|
|
1714
|
+
!isJavaScriptRecordFreeze(freeze.expression)) {
|
|
1715
|
+
return unsupportedSyntax("javascript", "record constructor without final Object.freeze(this)", nodeLocation(freeze ?? constructor, filename, source));
|
|
1716
|
+
}
|
|
1717
|
+
return withParserRanges(declaration, { name: identifierLocation(node.id, filename, source) });
|
|
1718
|
+
}
|
|
1719
|
+
/**
|
|
1720
|
+
* Recognizes the canonical source freeze or the generated identifier-free intrinsic owner.
|
|
1721
|
+
* @param {import("@babel/types").CallExpression} expression - Final constructor call.
|
|
1722
|
+
* @returns {boolean} Whether the call owns the native record-freeze operation.
|
|
1723
|
+
*/
|
|
1724
|
+
function isJavaScriptRecordFreeze(expression) {
|
|
1725
|
+
const callee = expression.callee;
|
|
1726
|
+
if (callee.type != "MemberExpression" || callee.computed || callee.optional ||
|
|
1727
|
+
callee.property.type != "Identifier" || callee.property.name != "freeze")
|
|
1728
|
+
return false;
|
|
1729
|
+
if (callee.object.type == "Identifier")
|
|
1730
|
+
return callee.object.name == "Object";
|
|
1731
|
+
if (callee.object.type != "MemberExpression" || callee.object.computed || callee.object.optional ||
|
|
1732
|
+
callee.object.property.type != "Identifier" || callee.object.property.name != "constructor")
|
|
1733
|
+
return false;
|
|
1734
|
+
return callee.object.object.type == "ObjectExpression" && callee.object.object.properties.length == 0 &&
|
|
1735
|
+
callee.object.object.extra?.parenthesized === true;
|
|
451
1736
|
}
|
|
452
1737
|
/**
|
|
453
1738
|
* Converts the existing exact if/else terminal shape.
|
|
@@ -456,26 +1741,53 @@ function convertFunction(node, language, filename, source, canonicalZeroRequired
|
|
|
456
1741
|
* @param {string} filename - Source filename.
|
|
457
1742
|
* @param {string} source - Complete source.
|
|
458
1743
|
* @param {boolean} canonicalZeroRequired - Whether generated scalar output may contain signed zero.
|
|
1744
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
459
1745
|
* @returns {import("../semantic/types.js").IfStatement} Semantic branch.
|
|
460
1746
|
*/
|
|
461
|
-
function convertIf(node, language, filename, source, canonicalZeroRequired) {
|
|
1747
|
+
function convertIf(node, language, filename, source, canonicalZeroRequired, context) {
|
|
462
1748
|
const location = nodeLocation(node, filename, source);
|
|
1749
|
+
const condition = convertExpression(node.test, language, filename, source, context);
|
|
1750
|
+
const consequentContext = { ...context, bindings: new Map(context.bindings) };
|
|
1751
|
+
const alternateContext = { ...context, bindings: new Map(context.bindings) };
|
|
463
1752
|
const consequent = node.consequent.type == "BlockStatement"
|
|
464
|
-
? convertBlock(node.consequent, language, filename, source, canonicalZeroRequired)
|
|
465
|
-
: convertBlock([node.consequent], language, filename, source, canonicalZeroRequired, nodeLocation(node.consequent, filename, source));
|
|
1753
|
+
? convertBlock(node.consequent, language, filename, source, canonicalZeroRequired, consequentContext)
|
|
1754
|
+
: convertBlock([node.consequent], language, filename, source, canonicalZeroRequired, consequentContext, nodeLocation(node.consequent, filename, source));
|
|
466
1755
|
const alternate = node.alternate
|
|
467
1756
|
? node.alternate.type == "BlockStatement"
|
|
468
|
-
? convertBlock(node.alternate, language, filename, source, canonicalZeroRequired)
|
|
469
|
-
: convertBlock([node.alternate], language, filename, source, canonicalZeroRequired, nodeLocation(node.alternate, filename, source))
|
|
1757
|
+
? convertBlock(node.alternate, language, filename, source, canonicalZeroRequired, alternateContext)
|
|
1758
|
+
: convertBlock([node.alternate], language, filename, source, canonicalZeroRequired, alternateContext, nodeLocation(node.alternate, filename, source))
|
|
470
1759
|
: undefined;
|
|
471
1760
|
return {
|
|
472
1761
|
...(alternate ? { alternate } : {}),
|
|
473
|
-
condition
|
|
1762
|
+
condition,
|
|
474
1763
|
consequent,
|
|
475
1764
|
kind: "IfStatement",
|
|
476
1765
|
location
|
|
477
1766
|
};
|
|
478
1767
|
}
|
|
1768
|
+
/**
|
|
1769
|
+
* Converts one exact block-bodied pre-condition loop.
|
|
1770
|
+
* @param {import("@babel/types").WhileStatement} node - Babel while statement.
|
|
1771
|
+
* @param {"javascript" | "typescript"} language - Frontend language.
|
|
1772
|
+
* @param {string} filename - Source filename.
|
|
1773
|
+
* @param {string} source - Complete source.
|
|
1774
|
+
* @param {boolean} canonicalZeroRequired - Whether generated scalar output may contain signed zero.
|
|
1775
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
1776
|
+
* @returns {import("../semantic/types.js").WhileStatement} Semantic loop.
|
|
1777
|
+
*/
|
|
1778
|
+
function convertWhile(node, language, filename, source, canonicalZeroRequired, context) {
|
|
1779
|
+
const location = nodeLocation(node, filename, source);
|
|
1780
|
+
if (node.body.type != "BlockStatement") {
|
|
1781
|
+
return unsupportedSyntax(language, "while without block body", nodeLocation(node.body, filename, source));
|
|
1782
|
+
}
|
|
1783
|
+
const bodyContext = { ...context, bindings: new Map(context.bindings) };
|
|
1784
|
+
return withParserRanges({
|
|
1785
|
+
body: convertBlock(node.body, language, filename, source, canonicalZeroRequired, bodyContext),
|
|
1786
|
+
condition: convertExpression(node.test, language, filename, source, context, undefined, true),
|
|
1787
|
+
kind: /** @type {const} */ ("WhileStatement"),
|
|
1788
|
+
location
|
|
1789
|
+
}, { keyword: tokenLocation(node, "while", node.start ?? 0, node.test.start ?? node.end ?? source.length, filename, source) });
|
|
1790
|
+
}
|
|
479
1791
|
/**
|
|
480
1792
|
* Reports whether Babel parsed an operation that makes generated JavaScript-family scalar output require zero canonicalization.
|
|
481
1793
|
* @param {unknown} value - Babel parser subtree.
|
|
@@ -522,9 +1834,10 @@ function hasCanonicalZeroReceiverWrapper(receiver, call) {
|
|
|
522
1834
|
* @param {string} filename - Source filename.
|
|
523
1835
|
* @param {string} source - Complete source.
|
|
524
1836
|
* @param {boolean} canonicalZeroRequired - Whether this parsed module contains a sign-producing integer operation.
|
|
1837
|
+
* @param {JavaScriptConversionContext} context - Typed lexical conversion context.
|
|
525
1838
|
* @returns {import("../semantic/types.js").PrintStatement} Print statement.
|
|
526
1839
|
*/
|
|
527
|
-
function convertPrint(node, language, filename, source, canonicalZeroRequired) {
|
|
1840
|
+
function convertPrint(node, language, filename, source, canonicalZeroRequired, context) {
|
|
528
1841
|
const location = nodeLocation(node, filename, source);
|
|
529
1842
|
if (node.type != "ExpressionStatement" || node.expression.type != "CallExpression") {
|
|
530
1843
|
return unsupportedSyntax(language, node.type, location);
|
|
@@ -549,7 +1862,7 @@ function convertPrint(node, language, filename, source, canonicalZeroRequired) {
|
|
|
549
1862
|
}
|
|
550
1863
|
argument = argument.callee.object;
|
|
551
1864
|
}
|
|
552
|
-
return { expression: convertExpression(argument, language, filename, source), kind: "PrintStatement", location };
|
|
1865
|
+
return { expression: convertExpression(argument, language, filename, source, context), kind: "PrintStatement", location };
|
|
553
1866
|
}
|
|
554
1867
|
/**
|
|
555
1868
|
* Parses JavaScript or TypeScript into the shared semantic module.
|
|
@@ -557,25 +1870,145 @@ function convertPrint(node, language, filename, source, canonicalZeroRequired) {
|
|
|
557
1870
|
* @param {string} input.filename - Source filename.
|
|
558
1871
|
* @param {"javascript" | "typescript"} input.language - Frontend language.
|
|
559
1872
|
* @param {string} input.source - Source text.
|
|
1873
|
+
* @param {readonly import("../semantic/types.js").EffectCapabilityDeclaration[]} [input.capabilities] - Compiler-authorized declarations.
|
|
1874
|
+
* @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>, valueRecords?: Map<string, import("../semantic/types.js").RecordDeclaration>}} [input.program] - Resolved program imports and entry role.
|
|
560
1875
|
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
561
1876
|
*/
|
|
562
|
-
export function parseJavaScriptTypeScript({ filename, language, source }) {
|
|
563
|
-
const file = parseBabelSource({ filename, language, source });
|
|
1877
|
+
export function parseJavaScriptTypeScript({ capabilities = [], filename, language, source, program }) {
|
|
1878
|
+
const file = parseBabelSource({ filename, language, source, sourceType: program ? "module" : "script" });
|
|
564
1879
|
const tokens = file.tokens ?? [];
|
|
565
1880
|
const tokenIndex = { byStart: new Map(tokens.map((token) => [token.start, token])), tokens };
|
|
566
1881
|
const canonicalZeroRequired = parserTreeRequiresCanonicalZero(file.program);
|
|
567
1882
|
rememberTokens(file, tokenIndex);
|
|
1883
|
+
const nullCheckOptOut = language == "typescript"
|
|
1884
|
+
? file.comments?.find((comment) => comment.value.trim() == "@ts-nocheck")
|
|
1885
|
+
: undefined;
|
|
1886
|
+
if (nullCheckOptOut) {
|
|
1887
|
+
return unsupportedSyntax(language, "disabled TypeScript checking directive", locationFromOffsets(filename, source, nullCheckOptOut.start ?? 0, nullCheckOptOut.end ?? source.length));
|
|
1888
|
+
}
|
|
568
1889
|
if (file.program.directives.length > 0) {
|
|
569
1890
|
return unsupportedSyntax(language, "top-level directive", nodeLocation(file.program.directives[0], filename, source));
|
|
570
1891
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
const
|
|
1892
|
+
/** @type {import("@babel/types").Statement[]} */
|
|
1893
|
+
let semanticNodes = [];
|
|
1894
|
+
for (const node of file.program.body) {
|
|
1895
|
+
if (node.type == "ImportDeclaration") {
|
|
1896
|
+
if (!program)
|
|
1897
|
+
return unsupportedSyntax(language, "import declaration", nodeLocation(node, filename, source));
|
|
1898
|
+
continue;
|
|
1899
|
+
}
|
|
1900
|
+
if (node.type == "ExportNamedDeclaration") {
|
|
1901
|
+
if (!program)
|
|
1902
|
+
return unsupportedSyntax(language, "export declaration", nodeLocation(node, filename, source));
|
|
1903
|
+
if (node.source || node.declaration && !["ClassDeclaration", "FunctionDeclaration"].includes(node.declaration.type)) {
|
|
1904
|
+
return unsupportedSyntax(language, "re-export or unsupported exported declaration", nodeLocation(node, filename, source));
|
|
1905
|
+
}
|
|
1906
|
+
if (node.declaration) {
|
|
1907
|
+
if (!node.declaration.leadingComments && node.leadingComments)
|
|
1908
|
+
node.declaration.leadingComments = node.leadingComments;
|
|
1909
|
+
semanticNodes.push(/** @type {import("@babel/types").ClassDeclaration | import("@babel/types").FunctionDeclaration} */ (node.declaration));
|
|
1910
|
+
}
|
|
1911
|
+
continue;
|
|
1912
|
+
}
|
|
1913
|
+
if (node.type == "ExportDefaultDeclaration" || node.type == "ExportAllDeclaration") {
|
|
1914
|
+
return unsupportedSyntax(language, node.type, nodeLocation(node, filename, source));
|
|
1915
|
+
}
|
|
1916
|
+
semanticNodes.push(node);
|
|
1917
|
+
}
|
|
1918
|
+
semanticNodes = task034JavaScriptNodes(semanticNodes, capabilities, language, filename, source);
|
|
1919
|
+
const classNodes = semanticNodes.filter((node) => node.type == "ClassDeclaration");
|
|
1920
|
+
const errorNodes = classNodes.filter((node) => node.superClass?.type == "Identifier" && node.superClass.name == "Error");
|
|
1921
|
+
const referenceClassNodes = classNodes.filter((node) => !errorNodes.includes(node) &&
|
|
1922
|
+
node.body.body.some((member) => member.type == "ClassProperty" || member.type == "ClassPrivateProperty"));
|
|
1923
|
+
const recordNodes = classNodes.filter((node) => !errorNodes.includes(node) && !referenceClassNodes.includes(node));
|
|
1924
|
+
const errorDeclarations = errorNodes.map((node, index) => ({
|
|
1925
|
+
id: `error:${index}`,
|
|
1926
|
+
kind: /** @type {const} */ ("ErrorDeclaration"),
|
|
1927
|
+
location: nodeLocation(node, filename, source),
|
|
1928
|
+
name: node.id?.name ?? ""
|
|
1929
|
+
}));
|
|
1930
|
+
const recordDeclarations = recordNodes.map((node, index) => {
|
|
1931
|
+
const id = `record:${index}`;
|
|
1932
|
+
const typeParameters = language == "typescript"
|
|
1933
|
+
? typeScriptTypeParameters(/** @type {import("@babel/types").TSTypeParameterDeclaration | null | undefined} */ (node.typeParameters), id, filename, source)
|
|
1934
|
+
: classJsdocTypeParameters(node, id, filename, source);
|
|
1935
|
+
return {
|
|
1936
|
+
fields: [],
|
|
1937
|
+
id,
|
|
1938
|
+
kind: /** @type {const} */ ("RecordDeclaration"),
|
|
1939
|
+
location: nodeLocation(node, filename, source),
|
|
1940
|
+
name: node.id?.name ?? "",
|
|
1941
|
+
...(typeParameters ? { typeParameters } : {})
|
|
1942
|
+
};
|
|
1943
|
+
});
|
|
1944
|
+
const classDeclarations = referenceClassNodes.map((node, index) => ({
|
|
1945
|
+
constructor: /** @type {import("../semantic/types.js").ConstructorDeclaration} */ ({}),
|
|
1946
|
+
fields: [], id: `class:${index}`, kind: /** @type {const} */ ("ClassDeclaration"),
|
|
1947
|
+
location: nodeLocation(node, filename, source), methods: [], name: node.id?.name ?? ""
|
|
1948
|
+
}));
|
|
1949
|
+
const recordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration | import("../semantic/types.js").EffectResourceDeclaration>} */ (new Map(program?.records ?? []));
|
|
1950
|
+
for (const resource of capabilities.flatMap(({ resources }) => resources))
|
|
1951
|
+
recordNames.set(resource.name, resource);
|
|
1952
|
+
const valueRecordNames = /** @type {Map<string, import("../semantic/types.js").RecordDeclaration | import("../semantic/types.js").ClassDeclaration>} */ (new Map(program?.valueRecords ?? program?.records ?? []));
|
|
1953
|
+
const errorNames = new Map(program?.errors ?? []);
|
|
1954
|
+
for (const failure of capabilities.flatMap(({ failures }) => failures)) {
|
|
1955
|
+
errorNames.set(failure.name, /** @type {import("../semantic/types.js").ErrorDeclaration} */ ( /** @type {unknown} */(failure)));
|
|
1956
|
+
}
|
|
1957
|
+
for (const declaration of errorDeclarations)
|
|
1958
|
+
errorNames.set(declaration.name, declaration);
|
|
1959
|
+
const errorsById = new Map([...errorNames.values()].map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
|
|
1960
|
+
const errors = errorNodes.map((node, index) => convertJavaScriptError(node, errorDeclarations[index], language, filename, source));
|
|
1961
|
+
for (const declaration of recordDeclarations)
|
|
1962
|
+
recordNames.set(declaration.name, declaration);
|
|
1963
|
+
for (const declaration of recordDeclarations)
|
|
1964
|
+
valueRecordNames.set(declaration.name, declaration);
|
|
1965
|
+
for (const declaration of classDeclarations)
|
|
1966
|
+
recordNames.set(declaration.name, declaration);
|
|
1967
|
+
for (const declaration of classDeclarations)
|
|
1968
|
+
valueRecordNames.set(declaration.name, declaration);
|
|
1969
|
+
const valueRecordsById = new Map(recordDeclarations.map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
|
|
1970
|
+
const classesById = new Map(classDeclarations.map((declaration) => [/** @type {string} */ (declaration.id), declaration]));
|
|
1971
|
+
const classes = referenceClassNodes.map((node, index) => predeclareReferenceClass(node, classDeclarations[index], recordNames, language, filename, source));
|
|
1972
|
+
const functionNodes = semanticNodes.filter((node) => node.type == "FunctionDeclaration");
|
|
1973
|
+
const signatures = functionNodes.map((node, index) => convertFunctionSignature(node, language, filename, source, recordNames, `function:${index}`));
|
|
1974
|
+
const functionSignatures = new Map([...program?.functions ?? []].map(([localName, declaration]) => [localName, {
|
|
1975
|
+
location: declaration.location,
|
|
1976
|
+
name: localName,
|
|
1977
|
+
nameLocation: declaration.location,
|
|
1978
|
+
parameters: declaration.parameters,
|
|
1979
|
+
returnType: declaration.returnType,
|
|
1980
|
+
...(declaration.typeParameters ? { typeParameters: declaration.typeParameters } : {})
|
|
1981
|
+
}]));
|
|
1982
|
+
for (const operation of capabilities.flatMap(({ operations }) => operations)) {
|
|
1983
|
+
if (!functionSignatures.has(operation.name))
|
|
1984
|
+
functionSignatures.set(operation.name, {
|
|
1985
|
+
location: moduleLocation(filename, source),
|
|
1986
|
+
name: operation.name,
|
|
1987
|
+
nameLocation: moduleLocation(filename, source),
|
|
1988
|
+
parameters: operation.parameters.map((parameter) => ({ ...parameter, kind: /** @type {const} */ ("Parameter"), location: moduleLocation(filename, source) })),
|
|
1989
|
+
returnType: operation.returnType
|
|
1990
|
+
});
|
|
1991
|
+
}
|
|
1992
|
+
for (const signature of signatures)
|
|
1993
|
+
functionSignatures.set(signature.name, signature);
|
|
1994
|
+
const records = recordNodes.map((node, index) => language == "typescript"
|
|
1995
|
+
? convertTypeScriptRecord(node, recordDeclarations[index], recordNames, filename, source)
|
|
1996
|
+
: convertJavaScriptRecord(node, recordDeclarations[index], recordNames, filename, source));
|
|
1997
|
+
for (let index = 0; index < referenceClassNodes.length; index += 1) {
|
|
1998
|
+
convertReferenceClassBodies(referenceClassNodes[index], classes[index], recordNames, valueRecordNames, valueRecordsById, classesById, functionSignatures, errorNames, errorsById, language, filename, source, canonicalZeroRequired);
|
|
1999
|
+
}
|
|
2000
|
+
const functions = functionNodes.map((node, index) => convertFunction(node, signatures[index], functionSignatures, recordNames, valueRecordNames, valueRecordsById, classesById, errorNames, errorsById, language, filename, source, canonicalZeroRequired));
|
|
2001
|
+
const entryNodes = semanticNodes.filter((node) => node.type != "FunctionDeclaration" && node.type != "ClassDeclaration");
|
|
574
2002
|
const location = moduleLocation(filename, source);
|
|
575
|
-
if (
|
|
576
|
-
return unsupportedSyntax(language, "
|
|
2003
|
+
if (program && !program.isEntry && entryNodes.length > 0) {
|
|
2004
|
+
return unsupportedSyntax(language, "top-level side effect outside the selected entry module", nodeLocation(entryNodes[0], filename, source));
|
|
2005
|
+
}
|
|
577
2006
|
const entryLocation = entryNodes.length == 0 ? location : locationFromOffsets(filename, source, entryNodes[0].start ?? 0, entryNodes.at(-1)?.end ?? source.length);
|
|
578
|
-
const entryBlock = convertBlock(entryNodes, language, filename, source, canonicalZeroRequired,
|
|
2007
|
+
const entryBlock = convertBlock(entryNodes, language, filename, source, canonicalZeroRequired, { bindings: new Map(), classes: classesById, errorNames, errors: errorsById, functions: functionSignatures,
|
|
2008
|
+
orderedMapDeclarations: orderedMapDeclarationsFor(entryNodes), recordNames, records: valueRecordsById, valueRecordNames }, entryLocation);
|
|
2009
|
+
if (!program && functions.length == 0 && capabilities.length == 0 && !blockReferencesProtectedEntry(entryBlock)) {
|
|
2010
|
+
return unsupportedSyntax(language, "module without a function", location);
|
|
2011
|
+
}
|
|
579
2012
|
return {
|
|
580
2013
|
entryPoint: {
|
|
581
2014
|
body: entryBlock,
|
|
@@ -584,29 +2017,328 @@ export function parseJavaScriptTypeScript({ filename, language, source }) {
|
|
|
584
2017
|
},
|
|
585
2018
|
functions,
|
|
586
2019
|
kind: "Module",
|
|
587
|
-
location
|
|
2020
|
+
location,
|
|
2021
|
+
...(errors.length > 0 ? { errors } : {}),
|
|
2022
|
+
...(classes.length > 0 ? { classes } : {}),
|
|
2023
|
+
...(records.length > 0 ? { records } : {})
|
|
588
2024
|
};
|
|
589
2025
|
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Removes exact protected Node probe support before portable conversion.
|
|
2028
|
+
* @param {import("@babel/types").Statement[]} nodes - Parsed top-level statements.
|
|
2029
|
+
* @param {readonly import("../semantic/types.js").EffectCapabilityDeclaration[]} capabilities - Authorized declarations.
|
|
2030
|
+
* @param {"javascript" | "typescript"} language - Source language.
|
|
2031
|
+
* @param {string} filename - Source filename.
|
|
2032
|
+
* @param {string} source - Complete source.
|
|
2033
|
+
* @returns {import("@babel/types").Statement[]} Portable statements.
|
|
2034
|
+
*/
|
|
2035
|
+
function task034JavaScriptNodes(nodes, capabilities, language, filename, source) {
|
|
2036
|
+
if (!isTask034ResourceProbe(capabilities))
|
|
2037
|
+
return nodes;
|
|
2038
|
+
const first = nodes[0];
|
|
2039
|
+
const marker = first?.leadingComments?.some((comment) => comment.type == "CommentBlock" &&
|
|
2040
|
+
comment.value.trim() == "semantifold-task034-support");
|
|
2041
|
+
if (!marker)
|
|
2042
|
+
return nodes;
|
|
2043
|
+
if (!hasExactEffectSupport(source, language)) {
|
|
2044
|
+
return unsupportedSyntax(language, "malformed protected Task 034 support", nodeLocation(first, filename, source));
|
|
2045
|
+
}
|
|
2046
|
+
const expected = [
|
|
2047
|
+
["VariableDeclaration", "__semantifoldTask034Fs"], ["ClassDeclaration", "ProbeOperationFailure"],
|
|
2048
|
+
["ClassDeclaration", "ProbeAcquireFailure"], ["ClassDeclaration", "ProbeReadFailure"],
|
|
2049
|
+
["ClassDeclaration", "ProbeCloseFailure"], ["ClassDeclaration", "ProbeResourceClosed"],
|
|
2050
|
+
["ClassDeclaration", "ProbeResource"], ["VariableDeclaration", "__semantifoldTask034Trace"],
|
|
2051
|
+
["FunctionDeclaration", "probeEffect"], ["FunctionDeclaration", "probeAcquire"],
|
|
2052
|
+
["FunctionDeclaration", "probeRead"], ["FunctionDeclaration", "probeClose"], ["FunctionDeclaration", "probeTrace"]
|
|
2053
|
+
];
|
|
2054
|
+
/**
|
|
2055
|
+
* Reads the declaration name used to verify one protected support statement.
|
|
2056
|
+
* @param {import("@babel/types").Statement | undefined} node - Candidate statement.
|
|
2057
|
+
* @returns {string | undefined} Declared name.
|
|
2058
|
+
*/
|
|
2059
|
+
const nodeName = (node) => {
|
|
2060
|
+
if (!node)
|
|
2061
|
+
return undefined;
|
|
2062
|
+
if (node.type == "VariableDeclaration" && node.declarations.length == 1 && node.declarations[0].id.type == "Identifier") {
|
|
2063
|
+
return node.declarations[0].id.name;
|
|
2064
|
+
}
|
|
2065
|
+
const id = Reflect.get(node, "id");
|
|
2066
|
+
return id && typeof id == "object" && typeof Reflect.get(id, "name") == "string" ? Reflect.get(id, "name") : undefined;
|
|
2067
|
+
};
|
|
2068
|
+
const matches = expected.every(([type, name], index) => nodes[index]?.type == type && nodeName(nodes[index]) == name);
|
|
2069
|
+
const next = nodes[expected.length];
|
|
2070
|
+
const ended = next?.leadingComments?.some((comment) => comment.type == "CommentBlock" &&
|
|
2071
|
+
comment.value.trim() == "semantifold-task034-support-end");
|
|
2072
|
+
if (!matches || next && !ended) {
|
|
2073
|
+
return unsupportedSyntax(language, "malformed protected Task 034 support", nodeLocation(first, filename, source));
|
|
2074
|
+
}
|
|
2075
|
+
return nodes.slice(expected.length);
|
|
2076
|
+
}
|
|
590
2077
|
/**
|
|
591
2078
|
* Invokes Babel and normalizes syntax failures.
|
|
592
2079
|
* @param {object} input - Parser input.
|
|
593
2080
|
* @param {string} input.filename - Source filename.
|
|
594
2081
|
* @param {"javascript" | "typescript"} input.language - Frontend language.
|
|
595
2082
|
* @param {string} input.source - Source text.
|
|
2083
|
+
* @param {"module" | "script"} input.sourceType - Explicit parser goal.
|
|
596
2084
|
* @returns {import("@babel/parser").ParseResult<import("@babel/types").File>} Babel file.
|
|
597
2085
|
*/
|
|
598
|
-
function parseBabelSource({ filename, language, source }) {
|
|
2086
|
+
function parseBabelSource({ filename, language, source, sourceType }) {
|
|
599
2087
|
try {
|
|
600
2088
|
return parseBabel(source, {
|
|
601
|
-
|
|
2089
|
+
allowAwaitOutsideFunction: true,
|
|
2090
|
+
plugins: language == "typescript" ? ["decorators-legacy", "typescript"] : ["decorators-legacy"],
|
|
602
2091
|
sourceFilename: filename,
|
|
603
|
-
sourceType
|
|
2092
|
+
sourceType,
|
|
604
2093
|
tokens: true
|
|
605
2094
|
});
|
|
606
2095
|
}
|
|
607
2096
|
catch (error) {
|
|
608
|
-
return parseFailure(language, error);
|
|
2097
|
+
return parseFailure(language, error, babelParserFailureLocation(error, filename, source));
|
|
2098
|
+
}
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Reads only parser-owned ESM import/export declarations for program assembly.
|
|
2102
|
+
* @param {object} input - Parser input.
|
|
2103
|
+
* @param {string} input.filename - Source filename.
|
|
2104
|
+
* @param {"javascript" | "typescript"} input.language - Frontend language.
|
|
2105
|
+
* @param {string} input.source - Source text.
|
|
2106
|
+
* @returns {{imports: {declarationLocation: import("../semantic/types.js").SourceLocation, importedName: string, importedNameLocation: import("../semantic/types.js").SourceLocation, localName: string, localNameLocation: import("../semantic/types.js").SourceLocation, location: import("../semantic/types.js").SourceLocation, pathLocation: import("../semantic/types.js").SourceLocation, specifier: string, stdlibCandidate?: true, typeOnly: boolean}[], exports: {declarationLocation?: import("../semantic/types.js").SourceLocation, exportedName: string, exportedNameLocation?: import("../semantic/types.js").SourceLocation, localName: string, localNameLocation?: import("../semantic/types.js").SourceLocation, location: import("../semantic/types.js").SourceLocation, typeOnly: boolean}[]}} Parser-owned ESM module header.
|
|
2107
|
+
*/
|
|
2108
|
+
export function inspectJavaScriptTypeScriptModule({ filename, language, source }) {
|
|
2109
|
+
const file = parseBabelSource({ filename, language, source, sourceType: "module" });
|
|
2110
|
+
const tokens = file.tokens ?? [];
|
|
2111
|
+
rememberTokens(file, { byStart: new Map(tokens.map((token) => [token.start, token])), tokens });
|
|
2112
|
+
const commonJs = findCommonJsNode(file.program);
|
|
2113
|
+
if (commonJs)
|
|
2114
|
+
unsupportedSyntax(language, "CommonJS require/module exports", nodeLocation(commonJs, filename, source));
|
|
2115
|
+
const imports = [];
|
|
2116
|
+
const exports = [];
|
|
2117
|
+
for (const node of file.program.body) {
|
|
2118
|
+
if (node.type == "ImportDeclaration") {
|
|
2119
|
+
const relative = node.source.value.startsWith("./") || node.source.value.startsWith("../");
|
|
2120
|
+
const stdlibCandidate = node.source.value.startsWith("semantifold:") || node.source.value.startsWith("node:");
|
|
2121
|
+
if (!relative && !stdlibCandidate) {
|
|
2122
|
+
unsupportedSyntax(language, "bare package import", nodeLocation(node.source, filename, source));
|
|
2123
|
+
}
|
|
2124
|
+
if (node.specifiers.length == 0)
|
|
2125
|
+
unsupportedSyntax(language, "side-effect-only import", nodeLocation(node, filename, source));
|
|
2126
|
+
if ((node.attributes?.length ?? 0) > 0 || (node.assertions?.length ?? 0) > 0 || Reflect.get(node, "phase")) {
|
|
2127
|
+
unsupportedSyntax(language, "import attributes or phase", nodeLocation(node, filename, source));
|
|
2128
|
+
}
|
|
2129
|
+
for (const specifier of node.specifiers) {
|
|
2130
|
+
if (specifier.type != "ImportSpecifier" || specifier.imported.type != "Identifier") {
|
|
2131
|
+
unsupportedSyntax(language, specifier.type, nodeLocation(specifier, filename, source));
|
|
2132
|
+
}
|
|
2133
|
+
imports.push({
|
|
2134
|
+
declarationLocation: nodeLocation(node, filename, source),
|
|
2135
|
+
importedName: specifier.imported.name,
|
|
2136
|
+
importedNameLocation: identifierLocation(specifier.imported, filename, source),
|
|
2137
|
+
localName: specifier.local.name,
|
|
2138
|
+
localNameLocation: identifierLocation(specifier.local, filename, source),
|
|
2139
|
+
location: nodeLocation(specifier, filename, source),
|
|
2140
|
+
pathLocation: nodeLocation(node.source, filename, source),
|
|
2141
|
+
specifier: node.source.value,
|
|
2142
|
+
...(!relative ? { stdlibCandidate: /** @type {const} */ (true) } : {}),
|
|
2143
|
+
typeOnly: node.importKind == "type" || specifier.importKind == "type"
|
|
2144
|
+
});
|
|
2145
|
+
}
|
|
2146
|
+
continue;
|
|
2147
|
+
}
|
|
2148
|
+
if (node.type == "ExportDefaultDeclaration" || node.type == "ExportAllDeclaration") {
|
|
2149
|
+
unsupportedSyntax(language, node.type, nodeLocation(node, filename, source));
|
|
2150
|
+
}
|
|
2151
|
+
if (node.type != "ExportNamedDeclaration")
|
|
2152
|
+
continue;
|
|
2153
|
+
if (node.source)
|
|
2154
|
+
unsupportedSyntax(language, "re-export", nodeLocation(node, filename, source));
|
|
2155
|
+
if (node.exportKind == "type")
|
|
2156
|
+
unsupportedSyntax(language, "type-only export", nodeLocation(node, filename, source));
|
|
2157
|
+
if (node.declaration) {
|
|
2158
|
+
if (node.declaration.type != "FunctionDeclaration" && node.declaration.type != "ClassDeclaration") {
|
|
2159
|
+
unsupportedSyntax(language, "unsupported exported declaration", nodeLocation(node.declaration, filename, source));
|
|
2160
|
+
}
|
|
2161
|
+
const identifier = node.declaration.id;
|
|
2162
|
+
if (!identifier)
|
|
2163
|
+
unsupportedSyntax(language, "anonymous exported declaration", nodeLocation(node.declaration, filename, source));
|
|
2164
|
+
exports.push({
|
|
2165
|
+
declarationLocation: nodeLocation(node, filename, source),
|
|
2166
|
+
exportedName: identifier.name,
|
|
2167
|
+
exportedNameLocation: identifierLocation(identifier, filename, source),
|
|
2168
|
+
localName: identifier.name,
|
|
2169
|
+
localNameLocation: identifierLocation(identifier, filename, source),
|
|
2170
|
+
location: identifierLocation(identifier, filename, source),
|
|
2171
|
+
typeOnly: /** @type {const} */ (false)
|
|
2172
|
+
});
|
|
2173
|
+
continue;
|
|
2174
|
+
}
|
|
2175
|
+
for (const specifier of node.specifiers) {
|
|
2176
|
+
if (specifier.type != "ExportSpecifier" || specifier.local.type != "Identifier" || specifier.exported.type != "Identifier") {
|
|
2177
|
+
unsupportedSyntax(language, specifier.type, nodeLocation(specifier, filename, source));
|
|
2178
|
+
}
|
|
2179
|
+
if (specifier.exportKind == "type")
|
|
2180
|
+
unsupportedSyntax(language, "type-only export", nodeLocation(specifier, filename, source));
|
|
2181
|
+
exports.push({
|
|
2182
|
+
declarationLocation: nodeLocation(node, filename, source),
|
|
2183
|
+
exportedName: specifier.exported.name,
|
|
2184
|
+
exportedNameLocation: identifierLocation(specifier.exported, filename, source),
|
|
2185
|
+
localName: specifier.local.name,
|
|
2186
|
+
localNameLocation: identifierLocation(specifier.local, filename, source),
|
|
2187
|
+
location: nodeLocation(specifier, filename, source),
|
|
2188
|
+
typeOnly: /** @type {const} */ (false)
|
|
2189
|
+
});
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
const dynamic = findFacadeUnsafeJavaScriptNode(file.program, "dynamic", new Set());
|
|
2193
|
+
if (dynamic)
|
|
2194
|
+
facadeFrontendFailure(language, "STDLIB_FACADE_DYNAMIC_REFERENCE", "Dynamic import cannot prove a standard-library facade identity.", nodeLocation(dynamic, filename, source));
|
|
2195
|
+
const stdlibBindings = new Set(imports.filter(({ stdlibCandidate }) => stdlibCandidate).map(({ localName }) => localName));
|
|
2196
|
+
if (stdlibBindings.size > 0) {
|
|
2197
|
+
const mutation = findFacadeUnsafeJavaScriptNode(file.program, "mutation", stdlibBindings);
|
|
2198
|
+
if (mutation)
|
|
2199
|
+
facadeFrontendFailure(language, "STDLIB_FACADE_SHADOWED", "A parser-proved standard-library facade binding cannot be reassigned or shadowed.", nodeLocation(mutation, filename, source));
|
|
2200
|
+
const reflection = findFacadeUnsafeJavaScriptNode(file.program, "reflection", stdlibBindings);
|
|
2201
|
+
if (reflection)
|
|
2202
|
+
facadeFrontendFailure(language, "STDLIB_FACADE_REFLECTION_UNSUPPORTED", "Reflective lookup cannot preserve a proved standard-library facade symbol identity.", nodeLocation(reflection, filename, source));
|
|
2203
|
+
}
|
|
2204
|
+
return { exports, imports };
|
|
2205
|
+
}
|
|
2206
|
+
/**
|
|
2207
|
+
* Finds parser-owned dynamic, mutating, or reflective constructs relevant to facade identity.
|
|
2208
|
+
* @param {unknown} value - Babel subtree.
|
|
2209
|
+
* @param {"dynamic" | "mutation" | "reflection"} mode - Rejected construct class.
|
|
2210
|
+
* @param {Set<string>} bindings - Parser-proved native facade bindings.
|
|
2211
|
+
* @param {WeakSet<object>} [seen] - Cycle guard.
|
|
2212
|
+
* @returns {import("@babel/types").Node | undefined} First rejected parser node.
|
|
2213
|
+
*/
|
|
2214
|
+
function findFacadeUnsafeJavaScriptNode(value, mode, bindings, seen = new WeakSet()) {
|
|
2215
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
2216
|
+
return undefined;
|
|
2217
|
+
seen.add(value);
|
|
2218
|
+
const node = /** @type {Record<string, unknown>} */ (value);
|
|
2219
|
+
if (mode == "dynamic" && node.type == "ImportExpression") {
|
|
2220
|
+
const sourceNode = node.source;
|
|
2221
|
+
if (isFacadeModuleStringNode(sourceNode))
|
|
2222
|
+
return /** @type {import("@babel/types").Node} */ (value);
|
|
2223
|
+
}
|
|
2224
|
+
if (mode == "dynamic" && node.type == "CallExpression" && node.callee && typeof node.callee == "object" &&
|
|
2225
|
+
Reflect.get(node.callee, "type") == "Import") {
|
|
2226
|
+
const arguments_ = Array.isArray(node.arguments) ? node.arguments : [];
|
|
2227
|
+
if (isFacadeModuleStringNode(arguments_[0]))
|
|
2228
|
+
return /** @type {import("@babel/types").Node} */ (value);
|
|
2229
|
+
}
|
|
2230
|
+
if (mode == "reflection" && node.type == "CallExpression" && node.callee && typeof node.callee == "object" &&
|
|
2231
|
+
Reflect.get(node.callee, "type") == "Identifier" && Reflect.get(node.callee, "name") == "eval") {
|
|
2232
|
+
return /** @type {import("@babel/types").Node} */ (value);
|
|
2233
|
+
}
|
|
2234
|
+
if (mode == "mutation" && (node.type == "AssignmentExpression" || node.type == "UpdateExpression")) {
|
|
2235
|
+
const target = node.type == "AssignmentExpression" ? node.left : node.argument;
|
|
2236
|
+
if (target && typeof target == "object" && Reflect.get(target, "type") == "Identifier" &&
|
|
2237
|
+
bindings.has(String(Reflect.get(target, "name"))))
|
|
2238
|
+
return /** @type {import("@babel/types").Node} */ (value);
|
|
2239
|
+
}
|
|
2240
|
+
for (const [key, child] of Object.entries(node)) {
|
|
2241
|
+
if (["extra", "innerComments", "leadingComments", "loc", "trailingComments"].includes(key))
|
|
2242
|
+
continue;
|
|
2243
|
+
if (Array.isArray(child)) {
|
|
2244
|
+
for (const item of child) {
|
|
2245
|
+
const found = findFacadeUnsafeJavaScriptNode(item, mode, bindings, seen);
|
|
2246
|
+
if (found)
|
|
2247
|
+
return found;
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
else {
|
|
2251
|
+
const found = findFacadeUnsafeJavaScriptNode(child, mode, bindings, seen);
|
|
2252
|
+
if (found)
|
|
2253
|
+
return found;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
return undefined;
|
|
2257
|
+
}
|
|
2258
|
+
/**
|
|
2259
|
+
* Checks a Babel string literal for one catalog-style stdlib module identity.
|
|
2260
|
+
* @param {unknown} value - Babel import argument/source node.
|
|
2261
|
+
* @returns {boolean} Whether the exact literal is a facade module candidate.
|
|
2262
|
+
*/
|
|
2263
|
+
function isFacadeModuleStringNode(value) {
|
|
2264
|
+
if (!value || typeof value != "object")
|
|
2265
|
+
return false;
|
|
2266
|
+
const node = /** @type {Record<string, unknown>} */ (value);
|
|
2267
|
+
const literal = node.value;
|
|
2268
|
+
return node.type == "StringLiteral" && typeof literal == "string" &&
|
|
2269
|
+
(literal.startsWith("semantifold:") || literal.startsWith("node:"));
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* Throws one stable located facade frontend diagnostic.
|
|
2273
|
+
* @param {"javascript" | "typescript"} language - Source language.
|
|
2274
|
+
* @param {string} code - Stable diagnostic code.
|
|
2275
|
+
* @param {string} message - Diagnostic detail.
|
|
2276
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Parser-owned location.
|
|
2277
|
+
* @returns {never} Always throws.
|
|
2278
|
+
*/
|
|
2279
|
+
function facadeFrontendFailure(language, code, message, location) {
|
|
2280
|
+
throw new SemantifoldDiagnostic({ code, language, location, message });
|
|
2281
|
+
}
|
|
2282
|
+
/**
|
|
2283
|
+
* Finds CommonJS constructs through Babel nodes rather than source-text matching.
|
|
2284
|
+
* @param {unknown} value - Babel subtree.
|
|
2285
|
+
* @param {WeakSet<object>} [seen] - Cycle guard.
|
|
2286
|
+
* @returns {import("@babel/types").Node | undefined} Unsupported node.
|
|
2287
|
+
*/
|
|
2288
|
+
function findCommonJsNode(value, seen = new WeakSet()) {
|
|
2289
|
+
if (!value || typeof value != "object" || seen.has(value))
|
|
2290
|
+
return undefined;
|
|
2291
|
+
seen.add(value);
|
|
2292
|
+
const node = /** @type {Record<string, unknown>} */ (value);
|
|
2293
|
+
if (node.type == "CallExpression") {
|
|
2294
|
+
const callee = node.callee;
|
|
2295
|
+
if (callee && typeof callee == "object" && Reflect.get(callee, "type") == "Identifier" && Reflect.get(callee, "name") == "require") {
|
|
2296
|
+
return /** @type {import("@babel/types").Node} */ (value);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
if (node.type == "MemberExpression") {
|
|
2300
|
+
const object = node.object;
|
|
2301
|
+
if (object && typeof object == "object" && Reflect.get(object, "type") == "Identifier" &&
|
|
2302
|
+
["exports", "module"].includes(String(Reflect.get(object, "name")))) {
|
|
2303
|
+
return /** @type {import("@babel/types").Node} */ (value);
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
2306
|
+
for (const [key, child] of Object.entries(node)) {
|
|
2307
|
+
if (["extra", "innerComments", "leadingComments", "loc", "trailingComments"].includes(key))
|
|
2308
|
+
continue;
|
|
2309
|
+
if (Array.isArray(child)) {
|
|
2310
|
+
for (const item of child) {
|
|
2311
|
+
const found = findCommonJsNode(item, seen);
|
|
2312
|
+
if (found)
|
|
2313
|
+
return found;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
else {
|
|
2317
|
+
const found = findCommonJsNode(child, seen);
|
|
2318
|
+
if (found)
|
|
2319
|
+
return found;
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
return undefined;
|
|
2323
|
+
}
|
|
2324
|
+
/**
|
|
2325
|
+
* Normalizes Babel's zero-based UTF-16 failure offset when available.
|
|
2326
|
+
* @param {unknown} error - Native Babel parser error.
|
|
2327
|
+
* @param {string} filename - Requested source filename.
|
|
2328
|
+
* @param {string} source - Complete source.
|
|
2329
|
+
* @returns {import("../semantic/types.js").SourceLocation} Failure range.
|
|
2330
|
+
*/
|
|
2331
|
+
function babelParserFailureLocation(error, filename, source) {
|
|
2332
|
+
if (!error || typeof error != "object")
|
|
2333
|
+
return moduleLocation(filename, source);
|
|
2334
|
+
const direct = Reflect.get(error, "pos");
|
|
2335
|
+
const parserLocation = Reflect.get(error, "loc");
|
|
2336
|
+
const located = parserLocation && typeof parserLocation == "object" ? Reflect.get(parserLocation, "index") : undefined;
|
|
2337
|
+
const offset = Number.isSafeInteger(direct) ? direct : located;
|
|
2338
|
+
if (typeof offset != "number" || !Number.isSafeInteger(offset) || offset < 0 || offset > source.length) {
|
|
2339
|
+
return moduleLocation(filename, source);
|
|
609
2340
|
}
|
|
2341
|
+
return locationFromOffsets(filename, source, offset, Math.min(offset + 1, source.length));
|
|
610
2342
|
}
|
|
611
2343
|
/**
|
|
612
2344
|
* Associates Babel nodes with their parser token stream without leaking it into semantic values.
|
|
@@ -630,4 +2362,4 @@ function rememberTokens(value, tokens, visited = new WeakSet()) {
|
|
|
630
2362
|
rememberTokens(child, tokens, visited);
|
|
631
2363
|
}
|
|
632
2364
|
}
|
|
633
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC10eXBlc2NyaXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9qYXZhc2NyaXB0LXR5cGVzY3JpcHQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxLQUFLLElBQUksVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFBO0FBQ2pELE9BQU8sRUFBQyxLQUFLLElBQUksWUFBWSxFQUFDLE1BQU0sZ0JBQWdCLENBQUE7QUFDcEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUM3RSxPQUFPLEVBQUMsbUJBQW1CLEVBQUUsY0FBYyxFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDM0UsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDN0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBRXBELDRIQUE0SDtBQUM1SCwwRkFBMEY7QUFFMUYsK0NBQStDO0FBQy9DLE1BQU0sVUFBVSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFDaEMsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNwQyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUM7SUFDWixDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUM7SUFDakIsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQztJQUNoQixDQUFDLEtBQUssRUFBRSxVQUFVLENBQUM7SUFDbkIsQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLENBQUMsSUFBSSxFQUFFLGlCQUFpQixDQUFDO0lBQ3pC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QUFDSCxTQUFTLGNBQWMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sR0FBRyxJQUFJLE9BQU8sRUFBRTtJQUM1RCxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTTtJQUU5QixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQ2xCLFVBQVUsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRTdCLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3pDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ3pCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSztnQkFBRSxJQUFJLElBQUksSUFBSSxPQUFPLElBQUksSUFBSSxRQUFRO29CQUFFLGNBQWMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFBO1FBQ3RHLENBQUM7YUFBTSxJQUFJLEtBQUssSUFBSSxPQUFPLEtBQUssSUFBSSxRQUFRO1lBQUUsY0FBYyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUE7SUFDdEYsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtwYXJzZSBhcyBwYXJzZUJhYmVsfSBmcm9tIFwiQGJhYmVsL3BhcnNlclwiXG5pbXBvcnQge3BhcnNlIGFzIHBhcnNlQ29tbWVudH0gZnJvbSBcImNvbW1lbnQtcGFyc2VyXCJcbmltcG9ydCB7bWlzc2luZ1R5cGUsIHBhcnNlRmFpbHVyZSwgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7bG9jYXRpb25Gcm9tT2Zmc2V0cywgbW9kdWxlTG9jYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7cmVxdWlyZVNvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuXG4vKiogQHR5cGVkZWYge05vbk51bGxhYmxlPGltcG9ydChcIkBiYWJlbC9wYXJzZXJcIikuUGFyc2VSZXN1bHQ8aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkZpbGU+W1widG9rZW5zXCJdPltudW1iZXJdfSBCYWJlbFRva2VuICovXG4vKiogQHR5cGVkZWYge3tieVN0YXJ0OiBNYXA8bnVtYmVyLCBCYWJlbFRva2VuPiwgdG9rZW5zOiBCYWJlbFRva2VuW119fSBCYWJlbFRva2VuSW5kZXggKi9cblxuLyoqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgQmFiZWxUb2tlbkluZGV4Pn0gKi9cbmNvbnN0IG5vZGVUb2tlbnMgPSBuZXcgV2Vha01hcCgpXG5jb25zdCBiYWJlbEJpbmFyeU9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wiK1wiLCBcIkFkZFwiXSxcbiAgW1wiLVwiLCBcIlN1YnRyYWN0XCJdLFxuICBbXCIqXCIsIFwiTXVsdGlwbHlcIl0sXG4gIFtcIj09PVwiLCBcIkVxdWFsXCJdLFxuICBbXCIhPT1cIiwgXCJOb3RFcXVhbFwiXSxcbiAgW1wiPFwiLCBcIkxlc3NUaGFuXCJdLFxuICBbXCI8PVwiLCBcIkxlc3NUaGFuT3JFcXVhbFwiXSxcbiAgW1wiPlwiLCBcIkdyZWF0ZXJUaGFuXCJdLFxuICBbXCI+PVwiLCBcIkdyZWF0ZXJUaGFuT3JFcXVhbFwiXVxuXSlcblxuLyoqXG4gKiBSZXR1cm5zIGEgc291cmNlIGxvY2F0aW9uIGZvciBhIEJhYmVsIG5vZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Ob2RlfSBub2RlIC0gQmFiZWwgbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IE5vcm1hbGl6ZWQgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICh0eXBlb2Ygbm9kZS5zdGFydCAhPSBcIm51bWJlclwiIHx8IHR5cGVvZiBub2RlLmVuZCAhPSBcIm51bWJlclwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBCYWJlbCBvbWl0dGVkIHNvdXJjZSBvZmZzZXRzIGZvciAke25vZGUudHlwZX0uYClcbiAgfVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIG5vZGUuc3RhcnQsIG5vZGUuZW5kKVxufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGlkZW50aWZpZXIgc3BlbGxpbmcgcmF0aGVyIHRoYW4gYSB0cmFpbGluZyBUeXBlU2NyaXB0IGFubm90YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5JZGVudGlmaWVyfSBub2RlIC0gUGFyc2VyIGlkZW50aWZpZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBJZGVudGlmaWVyIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBpZGVudGlmaWVyTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAodHlwZW9mIG5vZGUuc3RhcnQgIT0gXCJudW1iZXJcIikgdGhyb3cgbmV3IEVycm9yKFwiQmFiZWwgb21pdHRlZCBhbiBpZGVudGlmaWVyIHN0YXJ0IG9mZnNldC5cIilcbiAgY29uc3QgdG9rZW4gPSBub2RlVG9rZW5zLmdldChub2RlKT8uYnlTdGFydC5nZXQobm9kZS5zdGFydClcblxuICBpZiAoIXRva2VuIHx8IHRva2VuLnR5cGUubGFiZWwgIT0gXCJuYW1lXCIpIHRocm93IG5ldyBFcnJvcihgQmFiZWwgb21pdHRlZCB0aGUgaWRlbnRpZmllciB0b2tlbiBmb3IgJyR7bm9kZS5uYW1lfScuYClcblxuICByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCB0b2tlbi5zdGFydCwgdG9rZW4uZW5kKVxufVxuXG4vKipcbiAqIExvY2F0ZXMgb25lIEJhYmVsIHRva2VuIHdpdGhpbiBwYXJzZXItbm9kZSBib3VuZGFyaWVzLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gb3duZXIgLSBUb2tlbi1vd25pbmcgcGFyc2VyIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBFeGFjdCB0b2tlbiBzcGVsbGluZy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFydE9mZnNldCAtIEluY2x1c2l2ZSBib3VuZGFyeS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBlbmRPZmZzZXQgLSBFeGNsdXNpdmUgYm91bmRhcnkuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBFeGFjdCB0b2tlbiBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gdG9rZW5Mb2NhdGlvbihvd25lciwgdmFsdWUsIHN0YXJ0T2Zmc2V0LCBlbmRPZmZzZXQsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgdG9rZW5zID0gbm9kZVRva2Vucy5nZXQob3duZXIpPy50b2tlbnMgPz8gW11cbiAgbGV0IGxvdyA9IDBcbiAgbGV0IGhpZ2ggPSB0b2tlbnMubGVuZ3RoXG5cbiAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICBjb25zdCBtaWRkbGUgPSBNYXRoLmZsb29yKChsb3cgKyBoaWdoKSAvIDIpXG5cbiAgICBpZiAodG9rZW5zW21pZGRsZV0uc3RhcnQgPCBzdGFydE9mZnNldCkgbG93ID0gbWlkZGxlICsgMVxuICAgIGVsc2UgaGlnaCA9IG1pZGRsZVxuICB9XG4gIGxldCB0b2tlblxuXG4gIGZvciAobGV0IGluZGV4ID0gbG93OyBpbmRleCA8IHRva2Vucy5sZW5ndGggJiYgdG9rZW5zW2luZGV4XS5zdGFydCA8IGVuZE9mZnNldDsgaW5kZXgrKykge1xuICAgIGNvbnN0IGNhbmRpZGF0ZSA9IHRva2Vuc1tpbmRleF1cblxuICAgIGlmIChjYW5kaWRhdGUuZW5kIDw9IGVuZE9mZnNldCAmJiAoY2FuZGlkYXRlLnZhbHVlID09IHZhbHVlIHx8IGNhbmRpZGF0ZS50eXBlLmxhYmVsID09IHZhbHVlKSkge1xuICAgICAgdG9rZW4gPSBjYW5kaWRhdGVcbiAgICAgIGJyZWFrXG4gICAgfVxuICB9XG5cbiAgaWYgKCF0b2tlbikgdGhyb3cgbmV3IEVycm9yKGBCYWJlbCBvbWl0dGVkIHRva2VuICcke3ZhbHVlfScgYmV0d2VlbiAke3N0YXJ0T2Zmc2V0fSBhbmQgJHtlbmRPZmZzZXR9LmApXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgdG9rZW4uc3RhcnQsIHRva2VuLmVuZClcbn1cblxuLyoqXG4gKiBMb2NhdGVzIGEgY29tbWVudC1wYXJzZXIgdG9rZW4gaW5zaWRlIGEgQmFiZWwtb3duZWQgZG9jIGNvbW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Db21tZW50QmxvY2t9IGNvbW1lbnQgLSBCYWJlbCBkb2MgY29tbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiY29tbWVudC1wYXJzZXJcIikuU3BlY30gdGFnIC0gUGFyc2VkIGRvYyB0YWcuXG4gKiBAcGFyYW0ge1wibmFtZVwiIHwgXCJ0eXBlXCJ9IGZpZWxkIC0gVG9rZW4gZmllbGQuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBFeGFjdCB0b2tlbiBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHRhZywgZmllbGQsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbGluZSA9IHRhZy5zb3VyY2VbMF1cblxuICBpZiAodHlwZW9mIGNvbW1lbnQuc3RhcnQgIT0gXCJudW1iZXJcIiB8fCAhbGluZSkgdGhyb3cgbmV3IEVycm9yKGBDb21tZW50IHBhcnNlciBvbWl0dGVkIHRoZSBAJHt0YWcudGFnfSBzb3VyY2UgdG9rZW4uYClcblxuICBsZXQgbGluZVN0YXJ0ID0gY29tbWVudC5zdGFydFxuXG4gIGZvciAobGV0IGxpbmVOdW1iZXIgPSAwOyBsaW5lTnVtYmVyIDwgbGluZS5udW1iZXI7IGxpbmVOdW1iZXIrKykge1xuICAgIHdoaWxlIChsaW5lU3RhcnQgPCBzb3VyY2UubGVuZ3RoICYmIHNvdXJjZVtsaW5lU3RhcnRdICE9IFwiXFxyXCIgJiYgc291cmNlW2xpbmVTdGFydF0gIT0gXCJcXG5cIikgbGluZVN0YXJ0KytcbiAgICBpZiAoc291cmNlW2xpbmVTdGFydF0gPT0gXCJcXHJcIiAmJiBzb3VyY2VbbGluZVN0YXJ0ICsgMV0gPT0gXCJcXG5cIikgbGluZVN0YXJ0ICs9IDJcbiAgICBlbHNlIGxpbmVTdGFydCsrXG4gIH1cblxuICBjb25zdCBvcmRlcmVkRmllbGRzID0gW1wic3RhcnRcIiwgXCJkZWxpbWl0ZXJcIiwgXCJwb3N0RGVsaW1pdGVyXCIsIFwidGFnXCIsIFwicG9zdFRhZ1wiLCBcInR5cGVcIiwgXCJwb3N0VHlwZVwiLCBcIm5hbWVcIl1cbiAgY29uc3QgZmllbGRJbmRleCA9IG9yZGVyZWRGaWVsZHMuaW5kZXhPZihmaWVsZClcbiAgY29uc3Qgc3RhcnQgPSBsaW5lU3RhcnQgKyBvcmRlcmVkRmllbGRzLnNsaWNlKDAsIGZpZWxkSW5kZXgpLnJlZHVjZSgobGVuZ3RoLCBrZXkpID0+XG4gICAgbGVuZ3RoICsgbGluZS50b2tlbnNbLyoqIEB0eXBlIHtrZXlvZiB0eXBlb2YgbGluZS50b2tlbnN9ICovIChrZXkpXS5sZW5ndGgsIDApXG4gIGNvbnN0IHRva2VuID0gbGluZS50b2tlbnNbZmllbGRdXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgc3RhcnQsIHN0YXJ0ICsgdG9rZW4ubGVuZ3RoKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgc3VwcG9ydGVkIEJhYmVsIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5FeHByZXNzaW9ufSBub2RlIC0gQmFiZWwgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEV4cHJlc3Npb24obm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS50eXBlID09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbiwgbmFtZTogbm9kZS5uYW1lfSwge1xuICAgICAgbmFtZTogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJOdW1lcmljTGl0ZXJhbFwiKSB7XG4gICAgaWYgKCFOdW1iZXIuaXNTYWZlSW50ZWdlcihub2RlLnZhbHVlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcIm5vbi1zYWZlIGludGVnZXIgbGl0ZXJhbFwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJbnRlZ2VyTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBub2RlLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJCb29sZWFuTGl0ZXJhbFwiKSB7XG4gICAgaWYgKHR5cGVvZiBub2RlLnZhbHVlICE9IFwiYm9vbGVhblwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiaW52YWxpZCBib29sZWFuIGxpdGVyYWwgdmFsdWVcIiwgbG9jYXRpb24pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQm9vbGVhbkxpdGVyYWxcIiksIGxvY2F0aW9uLCB2YWx1ZTogbm9kZS52YWx1ZX0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiU3RyaW5nTGl0ZXJhbFwiKSB7XG4gICAgaWYgKHR5cGVvZiBub2RlLnZhbHVlICE9IFwic3RyaW5nXCIgfHwgIWhhc09ubHlVbmljb2RlU2NhbGFycyhub2RlLnZhbHVlKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImludmFsaWQgVW5pY29kZSBzdHJpbmcgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiU3RyaW5nTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBub2RlLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJUZW1wbGF0ZUxpdGVyYWxcIikge1xuICAgIGlmIChub2RlLmV4cHJlc3Npb25zLmxlbmd0aCA+IDApIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJpbnRlcnBvbGF0ZWQgc3RyaW5nXCIsIGxvY2F0aW9uKVxuXG4gICAgY29uc3QgcXVhc2kgPSBub2RlLnF1YXNpc1swXVxuXG4gICAgaWYgKHR5cGVvZiBxdWFzaS52YWx1ZS5jb29rZWQgIT0gXCJzdHJpbmdcIiB8fCAhaGFzT25seVVuaWNvZGVTY2FsYXJzKHF1YXNpLnZhbHVlLmNvb2tlZCkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJpbnZhbGlkIFVuaWNvZGUgc3RyaW5nIGxpdGVyYWxcIiwgbG9jYXRpb24pXG4gICAgfVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlN0cmluZ0xpdGVyYWxcIiksIGxvY2F0aW9uLCB2YWx1ZTogcXVhc2kudmFsdWUuY29va2VkfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJVbmFyeUV4cHJlc3Npb25cIiAmJiBbXCIhXCIsIFwiLVwiXS5pbmNsdWRlcyhub2RlLm9wZXJhdG9yKSkge1xuICAgIGNvbnN0IG9wZXJhbmQgPSBjb252ZXJ0RXhwcmVzc2lvbihub2RlLmFyZ3VtZW50LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBzZW1hbnRpYyA9IHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogXCJVbmFyeUV4cHJlc3Npb25cIixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgb3BlcmFuZFxuICAgIH0sIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKG5vZGUsIG5vZGUub3BlcmF0b3IsIG5vZGUuc3RhcnQgPz8gMCwgbm9kZS5hcmd1bWVudC5zdGFydCA/PyBub2RlLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pLCBub2RlLm9wZXJhdG9yID09IFwiIVwiID8gXCJOb3RcIiA6IFwiTmVnYXRlXCIpXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoc2VtYW50aWMpKVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkxvZ2ljYWxFeHByZXNzaW9uXCIgJiYgW1wiJiZcIiwgXCJ8fFwiXS5pbmNsdWRlcyhub2RlLm9wZXJhdG9yKSkge1xuICAgIGNvbnN0IHNlbWFudGljID0gd2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIkJpbmFyeUV4cHJlc3Npb25cIixcbiAgICAgIGxlZnQ6IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUubGVmdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICByaWdodDogY29udmVydEV4cHJlc3Npb24obm9kZS5yaWdodCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24obm9kZSwgbm9kZS5vcGVyYXRvciwgbm9kZS5sZWZ0LmVuZCA/PyBub2RlLnN0YXJ0ID8/IDAsIG5vZGUucmlnaHQuc3RhcnQgPz8gbm9kZS5lbmQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KSwgbm9kZS5vcGVyYXRvciA9PSBcIiYmXCIgPyBcIkFuZFwiIDogXCJPclwiKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHNlbWFudGljKSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIgJiYgYmFiZWxCaW5hcnlPcGVyYXRpb25zLmhhcyhub2RlLm9wZXJhdG9yKSkge1xuICAgIGlmIChub2RlLmxlZnQudHlwZSA9PSBcIlByaXZhdGVOYW1lXCIpIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBub2RlLmxlZnQudHlwZSwgbG9jYXRpb24pXG5cbiAgICBjb25zdCBsZWZ0ID0gY29udmVydEV4cHJlc3Npb24obm9kZS5sZWZ0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCByaWdodCA9IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUucmlnaHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiQmluYXJ5RXhwcmVzc2lvblwiLFxuICAgICAgbGVmdCxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgcmlnaHRcbiAgICB9LCB7XG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihub2RlLCBub2RlLm9wZXJhdG9yLCBub2RlLmxlZnQuZW5kID8/IG5vZGUuc3RhcnQgPz8gMCwgbm9kZS5yaWdodC5zdGFydCA/PyBub2RlLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pLCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL29wZXJhdG9ycy5qc1wiKS5BZGFwdGVkT3BlcmF0aW9ufSAqLyAoYmFiZWxCaW5hcnlPcGVyYXRpb25zLmdldChub2RlLm9wZXJhdG9yKSkpXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoc2VtYW50aWMpKVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIiAmJiBbXCI9PVwiLCBcIiE9XCJdLmluY2x1ZGVzKG5vZGUub3BlcmF0b3IpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBgY29lcmNpdmUgZXF1YWxpdHkgJHtub2RlLm9wZXJhdG9yfWAsIGxvY2F0aW9uKVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgbm9kZS5jYWxsZWUudHlwZSA9PSBcIklkZW50aWZpZXJcIikge1xuICAgIGNvbnN0IGFyZ3VtZW50c18gPSBub2RlLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50KSA9PiB7XG4gICAgICBpZiAoYXJndW1lbnQudHlwZSA9PSBcIlNwcmVhZEVsZW1lbnRcIiB8fCBhcmd1bWVudC50eXBlID09IFwiQXJndW1lbnRQbGFjZWhvbGRlclwiKSB7XG4gICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgYXJndW1lbnQudHlwZSwgbm9kZUxvY2F0aW9uKGFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGNvbnZlcnRFeHByZXNzaW9uKGFyZ3VtZW50LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2FyZ3VtZW50czogYXJndW1lbnRzXywgY2FsbGVlOiBub2RlLmNhbGxlZS5uYW1lLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJDYWxsRXhwcmVzc2lvblwiKSwgbG9jYXRpb259LCB7XG4gICAgICBjYWxsZWU6IGlkZW50aWZpZXJMb2NhdGlvbihub2RlLmNhbGxlZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBub2RlLnR5cGUsIGxvY2F0aW9uKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgc3VwcG9ydGVkIHJldHVybiBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdGF0ZW1lbnR9IG5vZGUgLSBCYWJlbCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJldHVyblN0YXRlbWVudH0gU2VtYW50aWMgcmV0dXJuLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UmV0dXJuKG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUudHlwZSAhPSBcIlJldHVyblN0YXRlbWVudFwiIHx8ICFub2RlLmFyZ3VtZW50KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIG5vZGUudHlwZSwgbG9jYXRpb24pXG5cbiAgcmV0dXJuIHtleHByZXNzaW9uOiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLmFyZ3VtZW50LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSksIGtpbmQ6IFwiUmV0dXJuU3RhdGVtZW50XCIsIGxvY2F0aW9ufVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBzdXBwb3J0ZWQgbG9jYWwgZGVjbGFyYXRpb24gb3IgYXNzaWdubWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlN0YXRlbWVudH0gbm9kZSAtIEJhYmVsIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTG9jYWxTdGF0ZW1lbnR9IFNlbWFudGljIGxvY2FsIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydExvY2FsU3RhdGVtZW50KG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIlZhcmlhYmxlRGVjbGFyYXRpb25cIikge1xuICAgIGlmICghW1wibGV0XCIsIFwiY29uc3RcIl0uaW5jbHVkZXMobm9kZS5raW5kKSB8fCBub2RlLmRlY2xhcmF0aW9ucy5sZW5ndGggIT0gMSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBgJHtub2RlLmtpbmR9IGRlY2xhcmF0aW9uYCwgbG9jYXRpb24pXG4gICAgfVxuXG4gICAgY29uc3QgZGVjbGFyYXRvciA9IG5vZGUuZGVjbGFyYXRpb25zWzBdXG4gICAgY29uc3QgZGVjbGFyYXRvckxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGRlY2xhcmF0b3IsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAoZGVjbGFyYXRvci5pZC50eXBlICE9IFwiSWRlbnRpZmllclwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGRlY2xhcmF0b3IuaWQudHlwZSwgZGVjbGFyYXRvckxvY2F0aW9uKVxuICAgIGlmICghZGVjbGFyYXRvci5pbml0KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwidW5pbml0aWFsaXplZCBkZWNsYXJhdGlvblwiLCBkZWNsYXJhdG9yTG9jYXRpb24pXG5cbiAgICBjb25zdCB0eXBlID0gbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCJcbiAgICAgID8gY29udmVydFR5cGVTY3JpcHRUeXBlKGRlY2xhcmF0b3IuaWQudHlwZUFubm90YXRpb24sIGBMb2NhbCAnJHtkZWNsYXJhdG9yLmlkLm5hbWV9J2AsIGRlY2xhcmF0b3JMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIDogbG9jYWxKYXZhU2NyaXB0VHlwZShub2RlLCBkZWNsYXJhdG9yLmlkLm5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBpbml0aWFsaXplcjogY29udmVydEV4cHJlc3Npb24oZGVjbGFyYXRvci5pbml0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBraW5kOiBcIkxvY2FsRGVjbGFyYXRpb25cIixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgbXV0YWJsZTogbm9kZS5raW5kID09IFwibGV0XCIsXG4gICAgICBuYW1lOiBkZWNsYXJhdG9yLmlkLm5hbWUsXG4gICAgICB0eXBlXG4gICAgfSwge1xuICAgICAgbmFtZTogaWRlbnRpZmllckxvY2F0aW9uKGRlY2xhcmF0b3IuaWQsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oZGVjbGFyYXRvciwgXCI9XCIsIGRlY2xhcmF0b3IuaWQuZW5kID8/IGRlY2xhcmF0b3Iuc3RhcnQgPz8gMCwgZGVjbGFyYXRvci5pbml0LnN0YXJ0ID8/IGRlY2xhcmF0b3IuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgJiYgbm9kZS5leHByZXNzaW9uLnR5cGUgPT0gXCJBc3NpZ25tZW50RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3QgYXNzaWdubWVudCA9IG5vZGUuZXhwcmVzc2lvblxuICAgIGNvbnN0IHRhcmdldExvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGFzc2lnbm1lbnQubGVmdCwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChhc3NpZ25tZW50Lm9wZXJhdG9yICE9IFwiPVwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGBhc3NpZ25tZW50ICR7YXNzaWdubWVudC5vcGVyYXRvcn1gLCBsb2NhdGlvbilcbiAgICBpZiAoYXNzaWdubWVudC5sZWZ0LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgYXNzaWdubWVudC5sZWZ0LnR5cGUsIHRhcmdldExvY2F0aW9uKVxuXG4gICAgY29uc3QgdGFyZ2V0ID0gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiksIGxvY2F0aW9uOiB0YXJnZXRMb2NhdGlvbiwgbmFtZTogYXNzaWdubWVudC5sZWZ0Lm5hbWV9LCB7XG4gICAgICBuYW1lOiBpZGVudGlmaWVyTG9jYXRpb24oYXNzaWdubWVudC5sZWZ0LCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBleHByZXNzaW9uOiBjb252ZXJ0RXhwcmVzc2lvbihhc3NpZ25tZW50LnJpZ2h0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBraW5kOiBcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgdGFyZ2V0XG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oYXNzaWdubWVudCwgXCI9XCIsIGFzc2lnbm1lbnQubGVmdC5lbmQgPz8gYXNzaWdubWVudC5zdGFydCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LnN0YXJ0ID8/IGFzc2lnbm1lbnQuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSlcbiAgfVxuXG4gIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBSZWFkcyBhbiBpbW1lZGlhdGVseSBhc3NvY2lhdGVkIEphdmFTY3JpcHQgbG9jYWwgYEB0eXBlYCB0YWcuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5WYXJpYWJsZURlY2xhcmF0aW9ufSBub2RlIC0gTG9jYWwgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIExvY2FsIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9IFNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGxvY2FsSmF2YVNjcmlwdFR5cGUobm9kZSwgbmFtZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBjb21tZW50ID0gbm9kZS5sZWFkaW5nQ29tbWVudHM/LmF0KC0xKVxuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmICghY29tbWVudCB8fCBjb21tZW50LnR5cGUgIT0gXCJDb21tZW50QmxvY2tcIiB8fCAhY29tbWVudC52YWx1ZS5zdGFydHNXaXRoKFwiKlwiKSkge1xuICAgIHJldHVybiBtaXNzaW5nVHlwZShcImphdmFzY3JpcHRcIiwgYExvY2FsICcke25hbWV9J2AsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgZ2FwID0gc291cmNlLnNsaWNlKGNvbW1lbnQuZW5kID8/IDAsIG5vZGUuc3RhcnQgPz8gMClcblxuICBpZiAoIS9eXFxzKiQvdS50ZXN0KGdhcCkgfHwgKGdhcC5tYXRjaCgvXFxuL2d1KT8ubGVuZ3RoID8/IDApID4gMSkge1xuICAgIHJldHVybiBtaXNzaW5nVHlwZShcImphdmFzY3JpcHRcIiwgYExvY2FsICcke25hbWV9J2AsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgYmxvY2sgPSBwYXJzZUNvbW1lbnQoYC8qJHtjb21tZW50LnZhbHVlfSovYClbMF1cbiAgY29uc3QgdGFncyA9IGJsb2NrPy50YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwidHlwZVwiKSA/PyBbXVxuXG4gIGNvbnN0IHRhZyA9IHRhZ3MubGVuZ3RoID09IDEgPyB0YWdzWzBdIDogdW5kZWZpbmVkXG5cbiAgcmV0dXJuIGNvbnZlcnRUeXBlKFxuICAgIHRhZz8udHlwZSxcbiAgICBcImphdmFzY3JpcHRcIixcbiAgICBgTG9jYWwgJyR7bmFtZX0nYCxcbiAgICBsb2NhdGlvbixcbiAgICB0YWcgPyBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgdGFnLCBcInR5cGVcIiwgZmlsZW5hbWUsIHNvdXJjZSkgOiBsb2NhdGlvblxuICApXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGV4aGF1c3RpdmUgQmFiZWwgc3RhdGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuU3RhdGVtZW50fSBub2RlIC0gQmFiZWwgc3RhdGVtZW50LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBnZW5lcmF0ZWQgc2NhbGFyIG91dHB1dCBtYXkgY29udGFpbiBzaWduZWQgemVyby5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdGF0ZW1lbnR9IFNlbWFudGljIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydFN0YXRlbWVudChub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkKSB7XG4gIGlmIChub2RlLnR5cGUgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikgcmV0dXJuIGNvbnZlcnRSZXR1cm4obm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGlmIChub2RlLnR5cGUgPT0gXCJJZlN0YXRlbWVudFwiKSByZXR1cm4gY29udmVydElmKG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQpXG4gIGlmIChub2RlLnR5cGUgPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIgfHwgbm9kZS50eXBlID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiICYmIG5vZGUuZXhwcmVzc2lvbi50eXBlID09IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBjb252ZXJ0TG9jYWxTdGF0ZW1lbnQobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIikgcmV0dXJuIGNvbnZlcnRQcmludChub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkKVxuXG4gIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIEJhYmVsIGJsb2NrIG9yIG5vcm1hbGl6ZWQgc2luZ2xlLXN0YXRlbWVudCBib2R5LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQmxvY2tTdGF0ZW1lbnQgfCBpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuU3RhdGVtZW50W119IGlucHV0IC0gUGFyc2VyIGJsb2NrIG9yIHN0YXRlbWVudHMuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtib29sZWFufSBjYW5vbmljYWxaZXJvUmVxdWlyZWQgLSBXaGV0aGVyIGdlbmVyYXRlZCBzY2FsYXIgb3V0cHV0IG1heSBjb250YWluIHNpZ25lZCB6ZXJvLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gW2xvY2F0aW9uXSAtIExvY2F0aW9uIGZvciBhIHN0YXRlbWVudC1hcnJheSBibG9jay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gU2VtYW50aWMgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhpbnB1dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgbG9jYXRpb24pIHtcbiAgY29uc3Qgc3RhdGVtZW50cyA9IEFycmF5LmlzQXJyYXkoaW5wdXQpID8gaW5wdXQgOiBpbnB1dC5ib2R5XG4gIGNvbnN0IGRpcmVjdGl2ZXMgPSBBcnJheS5pc0FycmF5KGlucHV0KSA/IFtdIDogaW5wdXQuZGlyZWN0aXZlc1xuICBjb25zdCBibG9ja0xvY2F0aW9uID0gbG9jYXRpb24gPz8gbm9kZUxvY2F0aW9uKC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkJsb2NrU3RhdGVtZW50fSAqLyAoaW5wdXQpLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChkaXJlY3RpdmVzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiZGlyZWN0aXZlXCIsIG5vZGVMb2NhdGlvbihkaXJlY3RpdmVzWzBdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiB7XG4gICAga2luZDogXCJCbG9ja1wiLFxuICAgIGxvY2F0aW9uOiBibG9ja0xvY2F0aW9uLFxuICAgIHN0YXRlbWVudHM6IHN0YXRlbWVudHMubWFwKChzdGF0ZW1lbnQpID0+IGNvbnZlcnRTdGF0ZW1lbnQoc3RhdGVtZW50LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkKSlcbiAgfVxufVxuXG4vKipcbiAqIFJlYWRzIEphdmFTY3JpcHQgSlNEb2MgdHlwZXMgZnJvbSBhIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gbm9kZSAtIEJhYmVsIGZ1bmN0aW9uIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge3twYXJhbWV0ZXJzOiBNYXA8c3RyaW5nLCB7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBzb3VyY2VUeXBlOiBzdHJpbmd9PiwgcmV0dXJuVHlwZToge2xvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgc291cmNlVHlwZTogc3RyaW5nfSB8IHVuZGVmaW5lZH19IFBhcnNlZCB0eXBlcy5cbiAqL1xuZnVuY3Rpb24ganNkb2NUeXBlcyhub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGNvbW1lbnQgPSBub2RlLmxlYWRpbmdDb21tZW50cz8uZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUudHlwZSA9PSBcIkNvbW1lbnRCbG9ja1wiICYmIGNhbmRpZGF0ZS52YWx1ZS5zdGFydHNXaXRoKFwiKlwiKSlcblxuICBpZiAoIWNvbW1lbnQpIG1pc3NpbmdUeXBlKFwiamF2YXNjcmlwdFwiLCBgRnVuY3Rpb24gJyR7bm9kZS5pZD8ubmFtZSA/PyBcImFub255bW91c1wifSdgLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG5cbiAgY29uc3QgY29tbWVudEJsb2NrID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ29tbWVudEJsb2NrfSAqLyAoY29tbWVudClcbiAgY29uc3QgYmxvY2sgPSBwYXJzZUNvbW1lbnQoYC8qJHtjb21tZW50QmxvY2sudmFsdWV9Ki9gKVswXVxuICBjb25zdCBwYXJhbWV0ZXJzID0gbmV3IE1hcChibG9jay50YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwicGFyYW1cIikubWFwKCh0YWcpID0+IFt0YWcubmFtZSwge1xuICAgIGxvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudEJsb2NrLCB0YWcsIFwidHlwZVwiLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBzb3VyY2VUeXBlOiB0YWcudHlwZVxuICB9XSkpXG4gIGNvbnN0IHJldHVyblRhZyA9IGJsb2NrLnRhZ3MuZmluZCgodGFnKSA9PiB0YWcudGFnID09IFwicmV0dXJuc1wiIHx8IHRhZy50YWcgPT0gXCJyZXR1cm5cIilcblxuICByZXR1cm4ge1xuICAgIHBhcmFtZXRlcnMsXG4gICAgcmV0dXJuVHlwZTogcmV0dXJuVGFnID8ge2xvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudEJsb2NrLCByZXR1cm5UYWcsIFwidHlwZVwiLCBmaWxlbmFtZSwgc291cmNlKSwgc291cmNlVHlwZTogcmV0dXJuVGFnLnR5cGV9IDogdW5kZWZpbmVkXG4gIH1cbn1cblxuLyoqXG4gKiBSZXF1aXJlcyBhIHN1cHBvcnRlZCBKYXZhU2NyaXB0IEpTRG9jIHNjYWxhciB0eXBlIHNwZWxsaW5nLlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHNvdXJjZVR5cGUgLSBTb3VyY2UtbGFuZ3VhZ2UgdHlwZS5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gU291cmNlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gW3R5cGVMb2NhdGlvbl0gLSBFeGFjdCB0eXBlIHRva2VuIGxvY2F0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9IFNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUeXBlKHNvdXJjZVR5cGUsIGxhbmd1YWdlLCBzdWJqZWN0LCBsb2NhdGlvbiwgdHlwZUxvY2F0aW9uID0gbG9jYXRpb24pIHtcbiAgcmV0dXJuIHJlcXVpcmVTb3VyY2VTY2FsYXJUeXBlKGxhbmd1YWdlLCBzb3VyY2VUeXBlLCBzdWJqZWN0LCBsb2NhdGlvbiwgdHlwZUxvY2F0aW9uKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBUeXBlU2NyaXB0IHNjYWxhciBrZXl3b3JkIGFubm90YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5UeXBlQW5ub3RhdGlvbiB8IGltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5UU1R5cGVBbm5vdGF0aW9uIHwgaW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLk5vb3AgfCBudWxsIHwgdW5kZWZpbmVkfSBhbm5vdGF0aW9uIC0gVHlwZSBhbm5vdGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBUeXBlZCBzdWJqZWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gb3duZXJMb2NhdGlvbiAtIE93bmluZyBkZWNsYXJhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gU2VtYW50aWMgc2NhbGFyIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUeXBlU2NyaXB0VHlwZShhbm5vdGF0aW9uLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICghYW5ub3RhdGlvbikgcmV0dXJuIG1pc3NpbmdUeXBlKFwidHlwZXNjcmlwdFwiLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uKVxuICBpZiAoYW5ub3RhdGlvbi50eXBlICE9IFwiVFNUeXBlQW5ub3RhdGlvblwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIsIG5vZGVMb2NhdGlvbihhbm5vdGF0aW9uLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGNvbnN0IHR5cGVOb2RlID0gYW5ub3RhdGlvbi50eXBlQW5ub3RhdGlvblxuICBjb25zdCBzb3VyY2VUeXBlID0gdHlwZU5vZGUudHlwZSA9PSBcIlRTTnVtYmVyS2V5d29yZFwiXG4gICAgPyBcIm51bWJlclwiXG4gICAgOiB0eXBlTm9kZS50eXBlID09IFwiVFNCb29sZWFuS2V5d29yZFwiXG4gICAgICA/IFwiYm9vbGVhblwiXG4gICAgICA6IHR5cGVOb2RlLnR5cGUgPT0gXCJUU1N0cmluZ0tleXdvcmRcIiA/IFwic3RyaW5nXCIgOiB1bmRlZmluZWRcblxuICBpZiAoIXNvdXJjZVR5cGUpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJ0eXBlc2NyaXB0XCIsIFwidW5zdXBwb3J0ZWQgc2NhbGFyIHR5cGVcIiwgbm9kZUxvY2F0aW9uKHR5cGVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiByZXF1aXJlU291cmNlU2NhbGFyVHlwZShcInR5cGVzY3JpcHRcIiwgc291cmNlVHlwZSwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgbm9kZUxvY2F0aW9uKHR5cGVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHN1cHBvcnRlZCBmdW5jdGlvbiBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IG5vZGUgLSBCYWJlbCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNhbm9uaWNhbFplcm9SZXF1aXJlZCAtIFdoZXRoZXIgZ2VuZXJhdGVkIHNjYWxhciBvdXRwdXQgbWF5IGNvbnRhaW4gc2lnbmVkIHplcm8uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gU2VtYW50aWMgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRGdW5jdGlvbihub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKCFub2RlLmlkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiYW5vbnltb3VzIGZ1bmN0aW9uXCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5hc3luYykgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImFzeW5jIGZ1bmN0aW9uXCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5nZW5lcmF0b3IpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJnZW5lcmF0b3IgZnVuY3Rpb25cIiwgbG9jYXRpb24pXG5cbiAgY29uc3QgZG9jdW1lbnRlZFR5cGVzID0gbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCIgPyBqc2RvY1R5cGVzKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIDogdW5kZWZpbmVkXG4gIGNvbnN0IHBhcmFtZXRlcnMgPSBub2RlLnBhcmFtcy5tYXAoKHBhcmFtZXRlcikgPT4ge1xuICAgIGNvbnN0IHBhcmFtZXRlckxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKHBhcmFtZXRlciwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChwYXJhbWV0ZXIudHlwZSAhPSBcIklkZW50aWZpZXJcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBwYXJhbWV0ZXIudHlwZSwgcGFyYW1ldGVyTG9jYXRpb24pXG5cbiAgICBjb25zdCBkb2N1bWVudGVkVHlwZSA9IGRvY3VtZW50ZWRUeXBlcz8ucGFyYW1ldGVycy5nZXQocGFyYW1ldGVyLm5hbWUpXG4gICAgY29uc3QgdHlwZSA9IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiXG4gICAgICA/IGNvbnZlcnRUeXBlKGRvY3VtZW50ZWRUeXBlPy5zb3VyY2VUeXBlLCBsYW5ndWFnZSwgYFBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIGRvY3VtZW50ZWRUeXBlPy5sb2NhdGlvbilcbiAgICAgIDogY29udmVydFR5cGVTY3JpcHRUeXBlKHBhcmFtZXRlci50eXBlQW5ub3RhdGlvbiwgYFBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQYXJhbWV0ZXJcIiksXG4gICAgICBsb2NhdGlvbjogcGFyYW1ldGVyTG9jYXRpb24sXG4gICAgICBuYW1lOiBwYXJhbWV0ZXIubmFtZSxcbiAgICAgIHR5cGVcbiAgICB9LCB7bmFtZTogaWRlbnRpZmllckxvY2F0aW9uKHBhcmFtZXRlciwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9KVxuICBjb25zdCByZXR1cm5Bbm5vdGF0aW9uID0gbm9kZS5yZXR1cm5UeXBlXG4gIGNvbnN0IHJldHVyblR5cGUgPSBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIlxuICAgID8gY29udmVydFR5cGUoZG9jdW1lbnRlZFR5cGVzPy5yZXR1cm5UeXBlPy5zb3VyY2VUeXBlLCBsYW5ndWFnZSwgYEZ1bmN0aW9uICcke25vZGUuaWQubmFtZX0nIHJldHVybmAsIGxvY2F0aW9uLCBkb2N1bWVudGVkVHlwZXM/LnJldHVyblR5cGU/LmxvY2F0aW9uKVxuICAgIDogY29udmVydFR5cGVTY3JpcHRUeXBlKHJldHVybkFubm90YXRpb24sIGBGdW5jdGlvbiAnJHtub2RlLmlkLm5hbWV9JyByZXR1cm5gLCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgYm9keSA9IGNvbnZlcnRCbG9jayhub2RlLmJvZHksIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQpXG5cbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGJvZHksXG4gICAga2luZDogXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIsXG4gICAgbG9jYXRpb24sXG4gICAgbmFtZTogbm9kZS5pZC5uYW1lLFxuICAgIHBhcmFtZXRlcnMsXG4gICAgcmV0dXJuVHlwZVxuICB9LCB7bmFtZTogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuaWQsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZXhpc3RpbmcgZXhhY3QgaWYvZWxzZSB0ZXJtaW5hbCBzaGFwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLklmU3RhdGVtZW50fSBub2RlIC0gQmFiZWwgaWYgc3RhdGVtZW50LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBnZW5lcmF0ZWQgc2NhbGFyIG91dHB1dCBtYXkgY29udGFpbiBzaWduZWQgemVyby5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gU2VtYW50aWMgYnJhbmNoLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0SWYobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBjb25zZXF1ZW50ID0gbm9kZS5jb25zZXF1ZW50LnR5cGUgPT0gXCJCbG9ja1N0YXRlbWVudFwiXG4gICAgPyBjb252ZXJ0QmxvY2sobm9kZS5jb25zZXF1ZW50LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkKVxuICAgIDogY29udmVydEJsb2NrKFtub2RlLmNvbnNlcXVlbnRdLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBub2RlTG9jYXRpb24obm9kZS5jb25zZXF1ZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgYWx0ZXJuYXRlID0gbm9kZS5hbHRlcm5hdGVcbiAgICA/IG5vZGUuYWx0ZXJuYXRlLnR5cGUgPT0gXCJCbG9ja1N0YXRlbWVudFwiXG4gICAgICA/IGNvbnZlcnRCbG9jayhub2RlLmFsdGVybmF0ZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZClcbiAgICAgIDogY29udmVydEJsb2NrKFtub2RlLmFsdGVybmF0ZV0sIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIG5vZGVMb2NhdGlvbihub2RlLmFsdGVybmF0ZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgOiB1bmRlZmluZWRcblxuICByZXR1cm4ge1xuICAgIC4uLihhbHRlcm5hdGUgPyB7YWx0ZXJuYXRlfSA6IHt9KSxcbiAgICBjb25kaXRpb246IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUudGVzdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIGNvbnNlcXVlbnQsXG4gICAga2luZDogXCJJZlN0YXRlbWVudFwiLFxuICAgIGxvY2F0aW9uXG4gIH1cbn1cblxuLyoqXG4gKiBSZXBvcnRzIHdoZXRoZXIgQmFiZWwgcGFyc2VkIGFuIG9wZXJhdGlvbiB0aGF0IG1ha2VzIGdlbmVyYXRlZCBKYXZhU2NyaXB0LWZhbWlseSBzY2FsYXIgb3V0cHV0IHJlcXVpcmUgemVybyBjYW5vbmljYWxpemF0aW9uLlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIEJhYmVsIHBhcnNlciBzdWJ0cmVlLlxuICogQHBhcmFtIHtXZWFrU2V0PG9iamVjdD59IFt2aXNpdGVkXSAtIEN5Y2xlIHByb3RlY3Rpb24uXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgc3VidHJlZSBjb250YWlucyBpbnRlZ2VyIG5lZ2F0aW9uIG9yIG11bHRpcGxpY2F0aW9uIHN5bnRheC5cbiAqL1xuZnVuY3Rpb24gcGFyc2VyVHJlZVJlcXVpcmVzQ2Fub25pY2FsWmVybyh2YWx1ZSwgdmlzaXRlZCA9IG5ldyBXZWFrU2V0KCkpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIikgcmV0dXJuIGZhbHNlXG4gIGlmICh2aXNpdGVkLmhhcyh2YWx1ZSkpIHJldHVybiBmYWxzZVxuXG4gIHZpc2l0ZWQuYWRkKHZhbHVlKVxuICBpZiAoUmVmbGVjdC5nZXQodmFsdWUsIFwidHlwZVwiKSA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiICYmIFJlZmxlY3QuZ2V0KHZhbHVlLCBcIm9wZXJhdG9yXCIpID09IFwiLVwiKSByZXR1cm4gdHJ1ZVxuICBpZiAoUmVmbGVjdC5nZXQodmFsdWUsIFwidHlwZVwiKSA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIiAmJiBSZWZsZWN0LmdldCh2YWx1ZSwgXCJvcGVyYXRvclwiKSA9PSBcIipcIikgcmV0dXJuIHRydWVcblxuICByZXR1cm4gT2JqZWN0LmVudHJpZXModmFsdWUpLnNvbWUoKFtrZXksIGNoaWxkXSkgPT5cbiAgICAhW1wiZXh0cmFcIiwgXCJpbm5lckNvbW1lbnRzXCIsIFwibGVhZGluZ0NvbW1lbnRzXCIsIFwibG9jXCIsIFwidHJhaWxpbmdDb21tZW50c1wiXS5pbmNsdWRlcyhrZXkpICYmXG4gICAgKEFycmF5LmlzQXJyYXkoY2hpbGQpXG4gICAgICA/IGNoaWxkLnNvbWUoKGl0ZW0pID0+IHBhcnNlclRyZWVSZXF1aXJlc0Nhbm9uaWNhbFplcm8oaXRlbSwgdmlzaXRlZCkpXG4gICAgICA6IHBhcnNlclRyZWVSZXF1aXJlc0Nhbm9uaWNhbFplcm8oY2hpbGQsIHZpc2l0ZWQpKSlcbn1cblxuLyoqXG4gKiBSZWNvZ25pemVzIHRoZSBwYXJzZXItb3duZWQgcmVjZWl2ZXIgcGFyZW50aGVzZXMgZW1pdHRlZCBvbmx5IGZvciBjYW5vbmljYWwgaW50ZWdlciBvdXRwdXQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5FeHByZXNzaW9uIHwgaW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlN1cGVyfSByZWNlaXZlciAtIFF1YWxpZmllZC1jYWxsIHJlY2VpdmVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ2FsbEV4cHJlc3Npb259IGNhbGwgLSBPdXRlciBgdG9TdHJpbmdgIGNhbGwuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgcmVjZWl2ZXIgaGFzIHRoZSBnZW5lcmF0ZWQgd3JhcHBlciBzaGFwZS5cbiAqL1xuZnVuY3Rpb24gaGFzQ2Fub25pY2FsWmVyb1JlY2VpdmVyV3JhcHBlcihyZWNlaXZlciwgY2FsbCkge1xuICBjb25zdCBleHRyYSA9IFJlZmxlY3QuZ2V0KHJlY2VpdmVyLCBcImV4dHJhXCIpXG4gIGNvbnN0IGV4cHJlc3Npb25QYXJlbnRoZXNlcyA9IFtcIkJpbmFyeUV4cHJlc3Npb25cIiwgXCJMb2dpY2FsRXhwcmVzc2lvblwiLCBcIlVuYXJ5RXhwcmVzc2lvblwiXS5pbmNsdWRlcyhyZWNlaXZlci50eXBlKSA/IDEgOiAwXG4gIGNvbnN0IHdyYXBwZXJQYXJlbnRoZXNlcyA9IGV4cHJlc3Npb25QYXJlbnRoZXNlcyArIDFcbiAgY29uc3QgcHJvcGVydHkgPSBjYWxsLmNhbGxlZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiID8gY2FsbC5jYWxsZWUucHJvcGVydHkgOiB1bmRlZmluZWRcblxuICByZXR1cm4gQm9vbGVhbihleHRyYSkgJiYgdHlwZW9mIGV4dHJhID09IFwib2JqZWN0XCIgJiYgUmVmbGVjdC5nZXQoZXh0cmEsIFwicGFyZW50aGVzaXplZFwiKSA9PT0gdHJ1ZSAmJlxuICAgIFJlZmxlY3QuZ2V0KGV4dHJhLCBcInBhcmVuU3RhcnRcIikgPT09IGNhbGwuc3RhcnQgJiYgdHlwZW9mIGNhbGwuc3RhcnQgPT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgY2FsbC5lbmQgPT0gXCJudW1iZXJcIiAmJlxuICAgIHR5cGVvZiByZWNlaXZlci5zdGFydCA9PSBcIm51bWJlclwiICYmIHR5cGVvZiByZWNlaXZlci5lbmQgPT0gXCJudW1iZXJcIiAmJiBwcm9wZXJ0eT8udHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJlxuICAgIHR5cGVvZiBwcm9wZXJ0eS5zdGFydCA9PSBcIm51bWJlclwiICYmIHR5cGVvZiBwcm9wZXJ0eS5lbmQgPT0gXCJudW1iZXJcIiAmJiBjYWxsLmNhbGxlZS5zdGFydCA9PT0gY2FsbC5zdGFydCAmJlxuICAgIHJlY2VpdmVyLnN0YXJ0ID09IGNhbGwuc3RhcnQgKyB3cmFwcGVyUGFyZW50aGVzZXMgJiYgcHJvcGVydHkuc3RhcnQgPT0gcmVjZWl2ZXIuZW5kICsgd3JhcHBlclBhcmVudGhlc2VzICsgMSAmJlxuICAgIHByb3BlcnR5LmVuZCA9PSBwcm9wZXJ0eS5zdGFydCArIFwidG9TdHJpbmdcIi5sZW5ndGggJiYgY2FsbC5lbmQgPT0gcHJvcGVydHkuZW5kICsgMlxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgY29uc29sZS5sb2cgZW50cnktcG9pbnQgY2FsbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlN0YXRlbWVudH0gbm9kZSAtIEJhYmVsIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNhbm9uaWNhbFplcm9SZXF1aXJlZCAtIFdoZXRoZXIgdGhpcyBwYXJzZWQgbW9kdWxlIGNvbnRhaW5zIGEgc2lnbi1wcm9kdWNpbmcgaW50ZWdlciBvcGVyYXRpb24uXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUHJpbnRTdGF0ZW1lbnR9IFByaW50IHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydFByaW50KG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS50eXBlICE9IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IG5vZGUuZXhwcmVzc2lvbi50eXBlICE9IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBsb2NhdGlvbilcbiAgfVxuXG4gIGNvbnN0IGNhbGwgPSBub2RlLmV4cHJlc3Npb25cbiAgY29uc3QgY2FsbGVlID0gY2FsbC5jYWxsZWVcblxuICBpZiAoY2FsbGVlLnR5cGUgIT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgfHwgY2FsbGVlLmNvbXB1dGVkIHx8IGNhbGxlZS5vYmplY3QudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fFxuICAgIGNhbGxlZS5vYmplY3QubmFtZSAhPSBcImNvbnNvbGVcIiB8fCBjYWxsZWUucHJvcGVydHkudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fCBjYWxsZWUucHJvcGVydHkubmFtZSAhPSBcImxvZ1wiIHx8XG4gICAgY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiZW50cnktcG9pbnQgZXhwcmVzc2lvblwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIGxldCBhcmd1bWVudCA9IGNhbGwuYXJndW1lbnRzWzBdXG5cbiAgaWYgKGFyZ3VtZW50LnR5cGUgPT0gXCJTcHJlYWRFbGVtZW50XCIgfHwgYXJndW1lbnQudHlwZSA9PSBcIkFyZ3VtZW50UGxhY2Vob2xkZXJcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgYXJndW1lbnQudHlwZSwgbm9kZUxvY2F0aW9uKGFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIGlmIChhcmd1bWVudC50eXBlID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiBhcmd1bWVudC5jYWxsZWUudHlwZSA9PSBcIk1lbWJlckV4cHJlc3Npb25cIiAmJiAhYXJndW1lbnQuY2FsbGVlLmNvbXB1dGVkICYmXG4gICAgIWFyZ3VtZW50LmNhbGxlZS5vcHRpb25hbCAmJiBhcmd1bWVudC5jYWxsZWUub2JqZWN0LnR5cGUgIT0gXCJTdXBlclwiICYmIGFyZ3VtZW50LmNhbGxlZS5wcm9wZXJ0eS50eXBlID09IFwiSWRlbnRpZmllclwiICYmXG4gICAgYXJndW1lbnQuY2FsbGVlLnByb3BlcnR5Lm5hbWUgPT0gXCJ0b1N0cmluZ1wiICYmICFhcmd1bWVudC5vcHRpb25hbCAmJiAhYXJndW1lbnQudHlwZUFyZ3VtZW50cyAmJlxuICAgICFhcmd1bWVudC50eXBlUGFyYW1ldGVycyAmJiBhcmd1bWVudC5hcmd1bWVudHMubGVuZ3RoID09IDApIHtcbiAgICBpZiAoIWNhbm9uaWNhbFplcm9SZXF1aXJlZCB8fCAhaGFzQ2Fub25pY2FsWmVyb1JlY2VpdmVyV3JhcHBlcihhcmd1bWVudC5jYWxsZWUub2JqZWN0LCBhcmd1bWVudCkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJlbnRyeS1wb2ludCBxdWFsaWZpZWQgY2FsbFwiLCBub2RlTG9jYXRpb24oYXJndW1lbnQuY2FsbGVlLnByb3BlcnR5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgYXJndW1lbnQgPSBhcmd1bWVudC5jYWxsZWUub2JqZWN0XG4gIH1cblxuICByZXR1cm4ge2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKGFyZ3VtZW50LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSksIGtpbmQ6IFwiUHJpbnRTdGF0ZW1lbnRcIiwgbG9jYXRpb259XG59XG5cbi8qKlxuICogUGFyc2VzIEphdmFTY3JpcHQgb3IgVHlwZVNjcmlwdCBpbnRvIHRoZSBzaGFyZWQgc2VtYW50aWMgbW9kdWxlLlxuICogQHBhcmFtIHtvYmplY3R9IGlucHV0IC0gUGFyc2VyIGlucHV0LlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LmZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBpbnB1dC5sYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LnNvdXJjZSAtIFNvdXJjZSB0ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBTZW1hbnRpYyBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUphdmFTY3JpcHRUeXBlU2NyaXB0KHtmaWxlbmFtZSwgbGFuZ3VhZ2UsIHNvdXJjZX0pIHtcbiAgY29uc3QgZmlsZSA9IHBhcnNlQmFiZWxTb3VyY2Uoe2ZpbGVuYW1lLCBsYW5ndWFnZSwgc291cmNlfSlcbiAgY29uc3QgdG9rZW5zID0gZmlsZS50b2tlbnMgPz8gW11cbiAgY29uc3QgdG9rZW5JbmRleCA9IHtieVN0YXJ0OiBuZXcgTWFwKHRva2Vucy5tYXAoKHRva2VuKSA9PiBbdG9rZW4uc3RhcnQsIHRva2VuXSkpLCB0b2tlbnN9XG4gIGNvbnN0IGNhbm9uaWNhbFplcm9SZXF1aXJlZCA9IHBhcnNlclRyZWVSZXF1aXJlc0Nhbm9uaWNhbFplcm8oZmlsZS5wcm9ncmFtKVxuXG4gIHJlbWVtYmVyVG9rZW5zKGZpbGUsIHRva2VuSW5kZXgpXG4gIGlmIChmaWxlLnByb2dyYW0uZGlyZWN0aXZlcy5sZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcInRvcC1sZXZlbCBkaXJlY3RpdmVcIiwgbm9kZUxvY2F0aW9uKGZpbGUucHJvZ3JhbS5kaXJlY3RpdmVzWzBdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCBmdW5jdGlvbnMgPSBmaWxlLnByb2dyYW0uYm9keS5maWx0ZXIoKG5vZGUpID0+IG5vZGUudHlwZSA9PSBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIilcbiAgICAubWFwKChub2RlKSA9PiBjb252ZXJ0RnVuY3Rpb24obm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCkpXG4gIGNvbnN0IGVudHJ5Tm9kZXMgPSBmaWxlLnByb2dyYW0uYm9keS5maWx0ZXIoKG5vZGUpID0+IG5vZGUudHlwZSAhPSBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIilcbiAgY29uc3QgbG9jYXRpb24gPSBtb2R1bGVMb2NhdGlvbihmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChmdW5jdGlvbnMubGVuZ3RoID09IDApIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJtb2R1bGUgd2l0aG91dCBhIGZ1bmN0aW9uXCIsIGxvY2F0aW9uKVxuICBjb25zdCBlbnRyeUxvY2F0aW9uID0gZW50cnlOb2Rlcy5sZW5ndGggPT0gMCA/IGxvY2F0aW9uIDogbG9jYXRpb25Gcm9tT2Zmc2V0cyhcbiAgICBmaWxlbmFtZSxcbiAgICBzb3VyY2UsXG4gICAgZW50cnlOb2Rlc1swXS5zdGFydCA/PyAwLFxuICAgIGVudHJ5Tm9kZXMuYXQoLTEpPy5lbmQgPz8gc291cmNlLmxlbmd0aFxuICApXG4gIGNvbnN0IGVudHJ5QmxvY2sgPSBjb252ZXJ0QmxvY2soZW50cnlOb2RlcywgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgZW50cnlMb2NhdGlvbilcblxuICByZXR1cm4ge1xuICAgIGVudHJ5UG9pbnQ6IHtcbiAgICAgIGJvZHk6IGVudHJ5QmxvY2ssXG4gICAgICBraW5kOiBcIkVudHJ5UG9pbnRcIixcbiAgICAgIGxvY2F0aW9uOiBlbnRyeUxvY2F0aW9uXG4gICAgfSxcbiAgICBmdW5jdGlvbnMsXG4gICAga2luZDogXCJNb2R1bGVcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogSW52b2tlcyBCYWJlbCBhbmQgbm9ybWFsaXplcyBzeW50YXggZmFpbHVyZXMuXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBQYXJzZXIgaW5wdXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGlucHV0Lmxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuc291cmNlIC0gU291cmNlIHRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiQGJhYmVsL3BhcnNlclwiKS5QYXJzZVJlc3VsdDxpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRmlsZT59IEJhYmVsIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlQmFiZWxTb3VyY2Uoe2ZpbGVuYW1lLCBsYW5ndWFnZSwgc291cmNlfSkge1xuICB0cnkge1xuICAgIHJldHVybiBwYXJzZUJhYmVsKHNvdXJjZSwge1xuICAgICAgcGx1Z2luczogbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgPyBbXCJ0eXBlc2NyaXB0XCJdIDogW10sXG4gICAgICBzb3VyY2VGaWxlbmFtZTogZmlsZW5hbWUsXG4gICAgICBzb3VyY2VUeXBlOiBcInNjcmlwdFwiLFxuICAgICAgdG9rZW5zOiB0cnVlXG4gICAgfSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gcGFyc2VGYWlsdXJlKGxhbmd1YWdlLCBlcnJvcilcbiAgfVxufVxuXG4vKipcbiAqIEFzc29jaWF0ZXMgQmFiZWwgbm9kZXMgd2l0aCB0aGVpciBwYXJzZXIgdG9rZW4gc3RyZWFtIHdpdGhvdXQgbGVha2luZyBpdCBpbnRvIHNlbWFudGljIHZhbHVlcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSB2YWx1ZSAtIEN1cnJlbnQgcGFyc2VyIHZhbHVlLlxuICogQHBhcmFtIHtCYWJlbFRva2VuSW5kZXh9IHRva2VucyAtIEluZGV4ZWQgcGFyc2VyIHRva2Vucy5cbiAqIEBwYXJhbSB7V2Vha1NldDxvYmplY3Q+fSBbdmlzaXRlZF0gLSBDeWNsZSBwcm90ZWN0aW9uLlxuICogQHJldHVybnMge3ZvaWR9XG4gKi9cbmZ1bmN0aW9uIHJlbWVtYmVyVG9rZW5zKHZhbHVlLCB0b2tlbnMsIHZpc2l0ZWQgPSBuZXcgV2Vha1NldCgpKSB7XG4gIGlmICh2aXNpdGVkLmhhcyh2YWx1ZSkpIHJldHVyblxuXG4gIHZpc2l0ZWQuYWRkKHZhbHVlKVxuICBub2RlVG9rZW5zLnNldCh2YWx1ZSwgdG9rZW5zKVxuXG4gIGZvciAoY29uc3QgY2hpbGQgb2YgT2JqZWN0LnZhbHVlcyh2YWx1ZSkpIHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShjaGlsZCkpIHtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjaGlsZCkgaWYgKGl0ZW0gJiYgdHlwZW9mIGl0ZW0gPT0gXCJvYmplY3RcIikgcmVtZW1iZXJUb2tlbnMoaXRlbSwgdG9rZW5zLCB2aXNpdGVkKVxuICAgIH0gZWxzZSBpZiAoY2hpbGQgJiYgdHlwZW9mIGNoaWxkID09IFwib2JqZWN0XCIpIHJlbWVtYmVyVG9rZW5zKGNoaWxkLCB0b2tlbnMsIHZpc2l0ZWQpXG4gIH1cbn1cbiJdfQ==
|
|
2365
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiamF2YXNjcmlwdC10eXBlc2NyaXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9qYXZhc2NyaXB0LXR5cGVzY3JpcHQuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxLQUFLLElBQUksVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFBO0FBQ2pELE9BQU8sRUFBQyxLQUFLLElBQUksWUFBWSxFQUFDLE1BQU0sZ0JBQWdCLENBQUE7QUFDcEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxZQUFZLEVBQUUscUJBQXFCLEVBQUUsaUJBQWlCLEVBQUMsTUFBTSxrQkFBa0IsQ0FBQTtBQUNwRyxPQUFPLEVBQUMsNkJBQTZCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUNwRSxPQUFPLEVBQUMsbUJBQW1CLEVBQUUsY0FBYyxFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDM0UsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sMEJBQTBCLENBQUE7QUFDN0QsT0FBTyxFQUFDLGdCQUFnQixFQUFDLE1BQU0sMkJBQTJCLENBQUE7QUFDMUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sNkJBQTZCLENBQUE7QUFDbEUsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sd0JBQXdCLENBQUE7QUFDNUQsT0FBTyxFQUFDLHVCQUF1QixFQUFFLHVCQUF1QixFQUFDLE1BQU0sY0FBYyxDQUFBO0FBQzdFLE9BQU8sRUFBQyxtQkFBbUIsRUFBRSwyQkFBMkIsRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxxQkFBcUIsRUFBRSxrQkFBa0IsRUFBRSxpQkFBaUIsRUFBRSxnQ0FBZ0MsRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFB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cGFyc2UgYXMgcGFyc2VCYWJlbH0gZnJvbSBcIkBiYWJlbC9wYXJzZXJcIlxuaW1wb3J0IHtwYXJzZSBhcyBwYXJzZUNvbW1lbnR9IGZyb20gXCJjb21tZW50LXBhcnNlclwiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBwYXJzZUZhaWx1cmUsIFNlbWFudGlmb2xkRGlhZ25vc3RpYywgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7YmxvY2tSZWZlcmVuY2VzUHJvdGVjdGVkRW50cnl9IGZyb20gXCIuLi9zZW1hbnRpYy9lZmZlY3RzLmpzXCJcbmltcG9ydCB7bG9jYXRpb25Gcm9tT2Zmc2V0cywgbW9kdWxlTG9jYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7aXNUYXNrMDM0UmVzb3VyY2VQcm9iZX0gZnJvbSBcIi4uL3NlbWFudGljL2NhcGFiaWxpdGllcy5qc1wiXG5pbXBvcnQge2hhc0V4YWN0RWZmZWN0U3VwcG9ydH0gZnJvbSBcIi4uL2JhY2tlbmRzL2VmZmVjdHMuanNcIlxuaW1wb3J0IHtyZXF1aXJlU291cmNlUmV0dXJuVHlwZSwgcmVxdWlyZVNvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuaW1wb3J0IHtkb2N1bWVudGVkVmFsdWVUeXBlLCBpbnN0YW50aWF0ZWRSZWNvcmRGaWVsZFR5cGUsIGl0ZXJhdGlvbkJpbmRpbmdUeXBlLCBpdGVyYXRpb25PcGVyYW5kVHlwZSwga25vd25DYWxsUmV0dXJuVHlwZSwgbGlzdFR5cGUsIG1hcFR5cGUsIG9wdGlvbmFsVHlwZSwgb3JkZXJlZE1hcFR5cGVGcm9tTWFwLCBvd25lZFJlZmVyZW5jZVR5cGUsIG93bmVkUmVzb3VyY2VUeXBlLCBwcmVzZXJ2ZXNHZW5lcmljT3B0aW9uYWxFdmlkZW5jZSwgcmVjb3JkVHlwZSwgcmVmZXJlbmNlVHlwZSwgdHlwZVZhcmlhYmxlfSBmcm9tIFwiLi90eXBlcy5qc1wiXG5cbi8qKiBAdHlwZWRlZiB7Tm9uTnVsbGFibGU8aW1wb3J0KFwiQGJhYmVsL3BhcnNlclwiKS5QYXJzZVJlc3VsdDxpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRmlsZT5bXCJ0b2tlbnNcIl0+W251bWJlcl19IEJhYmVsVG9rZW4gKi9cbi8qKiBAdHlwZWRlZiB7e2J5U3RhcnQ6IE1hcDxudW1iZXIsIEJhYmVsVG9rZW4+LCB0b2tlbnM6IEJhYmVsVG9rZW5bXX19IEJhYmVsVG9rZW5JbmRleCAqL1xuLyoqIEB0eXBlZGVmIHt7bmFtZTogc3RyaW5nLCBuYW1lTG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBwYXJhbWV0ZXJzOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QYXJhbWV0ZXJbXSwgcmV0dXJuVHlwZTogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGUsIHR5cGVQYXJhbWV0ZXJzPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcltdLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259fSBKYXZhU2NyaXB0RnVuY3Rpb25TaWduYXR1cmUgKi9cbi8qKiBAdHlwZWRlZiB7e2JpbmRpbmdzOiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0JpbmRpbmdUeXBlPiwgY2xhc3NlczogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbj4sIGN1cnJlbnRDbGFzcz86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24sIGVycm9yczogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JEZWNsYXJhdGlvbj4sIGVycm9yTmFtZXM6IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+LCBmdW5jdGlvbnM6IE1hcDxzdHJpbmcsIEphdmFTY3JpcHRGdW5jdGlvblNpZ25hdHVyZT4sIGxleGljYWxWYWx1ZU5hbWVzPzogU2V0PHN0cmluZz4sIG9yZGVyZWRNYXBEZWNsYXJhdGlvbnM/OiBTZXQ8b2JqZWN0PiwgcmVjb3JkTmFtZXM6IE1hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+LCByZWNvcmRzOiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbj4sIHJldHVyblR5cGU/OiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZSwgdHlwZVBhcmFtZXRlcnM/OiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUGFyYW1ldGVyPiwgdmFsdWVSZWNvcmROYW1lczogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn19IEphdmFTY3JpcHRDb252ZXJzaW9uQ29udGV4dCAqL1xuXG4vKiogQHR5cGUge1dlYWtNYXA8b2JqZWN0LCBCYWJlbFRva2VuSW5kZXg+fSAqL1xuY29uc3Qgbm9kZVRva2VucyA9IG5ldyBXZWFrTWFwKClcbmNvbnN0IHJlZmVyZW5jZU1ldGhvZEhvb2tzID0gbmV3IFNldChbXG4gIFwiX19kZWZpbmVHZXR0ZXJfX1wiLCBcIl9fZGVmaW5lU2V0dGVyX19cIiwgXCJfX2xvb2t1cEdldHRlcl9fXCIsIFwiX19sb29rdXBTZXR0ZXJfX1wiLCBcIl9fcHJvdG9fX1wiLCBcImNvbnN0cnVjdG9yXCIsXG4gIFwiaGFzT3duUHJvcGVydHlcIiwgXCJpc1Byb3RvdHlwZU9mXCIsIFwicHJvcGVydHlJc0VudW1lcmFibGVcIiwgXCJ0b0xvY2FsZVN0cmluZ1wiLCBcInRvU3RyaW5nXCIsIFwidmFsdWVPZlwiXG5dKVxuY29uc3QgYmFiZWxCaW5hcnlPcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIitcIiwgXCJBZGRcIl0sXG4gIFtcIi1cIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wiKlwiLCBcIk11bHRpcGx5XCJdLFxuICBbXCI9PT1cIiwgXCJFcXVhbFwiXSxcbiAgW1wiIT09XCIsIFwiTm90RXF1YWxcIl0sXG4gIFtcIjxcIiwgXCJMZXNzVGhhblwiXSxcbiAgW1wiPD1cIiwgXCJMZXNzVGhhbk9yRXF1YWxcIl0sXG4gIFtcIj5cIiwgXCJHcmVhdGVyVGhhblwiXSxcbiAgW1wiPj1cIiwgXCJHcmVhdGVyVGhhbk9yRXF1YWxcIl1cbl0pXG5cbi8qKlxuICogUmV0dXJucyBhIHNvdXJjZSBsb2NhdGlvbiBmb3IgYSBCYWJlbCBub2RlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gbm9kZSAtIEJhYmVsIG5vZGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBOb3JtYWxpemVkIGxvY2F0aW9uLlxuICovXG5mdW5jdGlvbiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAodHlwZW9mIG5vZGUuc3RhcnQgIT0gXCJudW1iZXJcIiB8fCB0eXBlb2Ygbm9kZS5lbmQgIT0gXCJudW1iZXJcIikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQmFiZWwgb21pdHRlZCBzb3VyY2Ugb2Zmc2V0cyBmb3IgJHtub2RlLnR5cGV9LmApXG4gIH1cblxuICByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBub2RlLnN0YXJ0LCBub2RlLmVuZClcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBpZGVudGlmaWVyIHNwZWxsaW5nIHJhdGhlciB0aGFuIGEgdHJhaWxpbmcgVHlwZVNjcmlwdCBhbm5vdGF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuSWRlbnRpZmllcn0gbm9kZSAtIFBhcnNlciBpZGVudGlmaWVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gSWRlbnRpZmllciBsb2NhdGlvbi5cbiAqL1xuZnVuY3Rpb24gaWRlbnRpZmllckxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgaWYgKHR5cGVvZiBub2RlLnN0YXJ0ICE9IFwibnVtYmVyXCIpIHRocm93IG5ldyBFcnJvcihcIkJhYmVsIG9taXR0ZWQgYW4gaWRlbnRpZmllciBzdGFydCBvZmZzZXQuXCIpXG4gIGNvbnN0IHRva2VuID0gbm9kZVRva2Vucy5nZXQobm9kZSk/LmJ5U3RhcnQuZ2V0KG5vZGUuc3RhcnQpXG5cbiAgaWYgKCF0b2tlbiB8fCB0b2tlbi50eXBlLmxhYmVsICE9IFwibmFtZVwiKSB0aHJvdyBuZXcgRXJyb3IoYEJhYmVsIG9taXR0ZWQgdGhlIGlkZW50aWZpZXIgdG9rZW4gZm9yICcke25vZGUubmFtZX0nLmApXG5cbiAgcmV0dXJuIGxvY2F0aW9uRnJvbU9mZnNldHMoZmlsZW5hbWUsIHNvdXJjZSwgdG9rZW4uc3RhcnQsIHRva2VuLmVuZClcbn1cblxuLyoqXG4gKiBMb2NhdGVzIG9uZSBCYWJlbCB0b2tlbiB3aXRoaW4gcGFyc2VyLW5vZGUgYm91bmRhcmllcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLk5vZGV9IG93bmVyIC0gVG9rZW4tb3duaW5nIHBhcnNlciBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gRXhhY3QgdG9rZW4gc3BlbGxpbmcuXG4gKiBAcGFyYW0ge251bWJlcn0gc3RhcnRPZmZzZXQgLSBJbmNsdXNpdmUgYm91bmRhcnkuXG4gKiBAcGFyYW0ge251bWJlcn0gZW5kT2Zmc2V0IC0gRXhjbHVzaXZlIGJvdW5kYXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgdG9rZW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIHRva2VuTG9jYXRpb24ob3duZXIsIHZhbHVlLCBzdGFydE9mZnNldCwgZW5kT2Zmc2V0LCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IHRva2VucyA9IG5vZGVUb2tlbnMuZ2V0KG93bmVyKT8udG9rZW5zID8/IFtdXG4gIGxldCBsb3cgPSAwXG4gIGxldCBoaWdoID0gdG9rZW5zLmxlbmd0aFxuXG4gIHdoaWxlIChsb3cgPCBoaWdoKSB7XG4gICAgY29uc3QgbWlkZGxlID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKVxuXG4gICAgaWYgKHRva2Vuc1ttaWRkbGVdLnN0YXJ0IDwgc3RhcnRPZmZzZXQpIGxvdyA9IG1pZGRsZSArIDFcbiAgICBlbHNlIGhpZ2ggPSBtaWRkbGVcbiAgfVxuICBsZXQgdG9rZW5cblxuICBmb3IgKGxldCBpbmRleCA9IGxvdzsgaW5kZXggPCB0b2tlbnMubGVuZ3RoICYmIHRva2Vuc1tpbmRleF0uc3RhcnQgPCBlbmRPZmZzZXQ7IGluZGV4KyspIHtcbiAgICBjb25zdCBjYW5kaWRhdGUgPSB0b2tlbnNbaW5kZXhdXG5cbiAgICBpZiAoY2FuZGlkYXRlLmVuZCA8PSBlbmRPZmZzZXQgJiYgKGNhbmRpZGF0ZS52YWx1ZSA9PSB2YWx1ZSB8fCBjYW5kaWRhdGUudHlwZS5sYWJlbCA9PSB2YWx1ZSkpIHtcbiAgICAgIHRva2VuID0gY2FuZGlkYXRlXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuXG4gIGlmICghdG9rZW4pIHRocm93IG5ldyBFcnJvcihgQmFiZWwgb21pdHRlZCB0b2tlbiAnJHt2YWx1ZX0nIGJldHdlZW4gJHtzdGFydE9mZnNldH0gYW5kICR7ZW5kT2Zmc2V0fS5gKVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIHRva2VuLnN0YXJ0LCB0b2tlbi5lbmQpXG59XG5cbi8qKlxuICogTG9jYXRlcyBhIGNvbW1lbnQtcGFyc2VyIHRva2VuIGluc2lkZSBhIEJhYmVsLW93bmVkIGRvYyBjb21tZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ29tbWVudEJsb2NrfSBjb21tZW50IC0gQmFiZWwgZG9jIGNvbW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcImNvbW1lbnQtcGFyc2VyXCIpLlNwZWN9IHRhZyAtIFBhcnNlZCBkb2MgdGFnLlxuICogQHBhcmFtIHtcIm5hbWVcIiB8IFwidHlwZVwifSBmaWVsZCAtIFRva2VuIGZpZWxkLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgdG9rZW4gbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGNvbW1lbnRUYWdMb2NhdGlvbihjb21tZW50LCB0YWcsIGZpZWxkLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxpbmUgPSB0YWcuc291cmNlWzBdXG5cbiAgaWYgKHR5cGVvZiBjb21tZW50LnN0YXJ0ICE9IFwibnVtYmVyXCIgfHwgIWxpbmUpIHRocm93IG5ldyBFcnJvcihgQ29tbWVudCBwYXJzZXIgb21pdHRlZCB0aGUgQCR7dGFnLnRhZ30gc291cmNlIHRva2VuLmApXG5cbiAgbGV0IGxpbmVTdGFydCA9IGNvbW1lbnQuc3RhcnRcblxuICBmb3IgKGxldCBsaW5lTnVtYmVyID0gMDsgbGluZU51bWJlciA8IGxpbmUubnVtYmVyOyBsaW5lTnVtYmVyKyspIHtcbiAgICB3aGlsZSAobGluZVN0YXJ0IDwgc291cmNlLmxlbmd0aCAmJiBzb3VyY2VbbGluZVN0YXJ0XSAhPSBcIlxcclwiICYmIHNvdXJjZVtsaW5lU3RhcnRdICE9IFwiXFxuXCIpIGxpbmVTdGFydCsrXG4gICAgaWYgKHNvdXJjZVtsaW5lU3RhcnRdID09IFwiXFxyXCIgJiYgc291cmNlW2xpbmVTdGFydCArIDFdID09IFwiXFxuXCIpIGxpbmVTdGFydCArPSAyXG4gICAgZWxzZSBsaW5lU3RhcnQrK1xuICB9XG5cbiAgY29uc3Qgb3JkZXJlZEZpZWxkcyA9IFtcInN0YXJ0XCIsIFwiZGVsaW1pdGVyXCIsIFwicG9zdERlbGltaXRlclwiLCBcInRhZ1wiLCBcInBvc3RUYWdcIiwgXCJ0eXBlXCIsIFwicG9zdFR5cGVcIiwgXCJuYW1lXCJdXG4gIGNvbnN0IGZpZWxkSW5kZXggPSBvcmRlcmVkRmllbGRzLmluZGV4T2YoZmllbGQpXG4gIGxldCBzdGFydCA9IGxpbmVTdGFydCArIG9yZGVyZWRGaWVsZHMuc2xpY2UoMCwgZmllbGRJbmRleCkucmVkdWNlKChsZW5ndGgsIGtleSkgPT5cbiAgICBsZW5ndGggKyBsaW5lLnRva2Vuc1svKiogQHR5cGUge2tleW9mIHR5cGVvZiBsaW5lLnRva2Vuc30gKi8gKGtleSldLmxlbmd0aCwgMClcbiAgY29uc3QgdG9rZW4gPSBsaW5lLnRva2Vuc1tmaWVsZF1cbiAgbGV0IGxlbmd0aCA9IHRva2VuLmxlbmd0aFxuXG4gIGlmIChmaWVsZCA9PSBcInR5cGVcIiAmJiB0YWcudHlwZSkge1xuICAgIGNvbnN0IG5lc3RlZE9mZnNldCA9IHRva2VuLmluZGV4T2YodGFnLnR5cGUpXG5cbiAgICBpZiAobmVzdGVkT2Zmc2V0IDwgMCkgdGhyb3cgbmV3IEVycm9yKGBDb21tZW50IHBhcnNlciBvbWl0dGVkIHRoZSBAJHt0YWcudGFnfSB0eXBlIHNwZWxsaW5nLmApXG4gICAgc3RhcnQgKz0gbmVzdGVkT2Zmc2V0XG4gICAgbGVuZ3RoID0gdGFnLnR5cGUubGVuZ3RoXG4gIH1cblxuICByZXR1cm4gbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBzdGFydCwgc3RhcnQgKyBsZW5ndGgpXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIGBNYXBgIHJlc29sdmVzIHRvIHRoZSBuYXRpdmUgaW50cmluc2ljIGluIHRoZSBjdXJyZW50IGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge0phdmFTY3JpcHRDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGxleGljYWwgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgbmF0aXZlIE1hcCBjb25zdHJ1Y3Rpb24gaXMgdW5zaGFkb3dlZC5cbiAqL1xuZnVuY3Rpb24gbmF0aXZlTWFwQXZhaWxhYmxlKGNvbnRleHQpIHtcbiAgcmV0dXJuICFjb250ZXh0LmJpbmRpbmdzLmhhcyhcIk1hcFwiKSAmJiAhY29udGV4dC5sZXhpY2FsVmFsdWVOYW1lcz8uaGFzKFwiTWFwXCIpICYmXG4gICAgIWNvbnRleHQuZnVuY3Rpb25zLmhhcyhcIk1hcFwiKSAmJiAhY29udGV4dC52YWx1ZVJlY29yZE5hbWVzLmhhcyhcIk1hcFwiKSAmJiAhY29udGV4dC5lcnJvck5hbWVzLmhhcyhcIk1hcFwiKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgc3VwcG9ydGVkIEJhYmVsIGV4cHJlc3Npb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5FeHByZXNzaW9ufSBub2RlIC0gQmFiZWwgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge0phdmFTY3JpcHRDb252ZXJzaW9uQ29udGV4dH0gW2NvbnRleHRdIC0gVHlwZWQgbGV4aWNhbCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSBbZXhwZWN0ZWRUeXBlXSAtIEV4cGxpY2l0IGNvbnRleHR1YWwgdmFsdWUgdHlwZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3ByZXNlcnZlT3B0aW9uYWxdIC0gV2hldGhlciBhbiBvcHRpb25hbCBpZGVudGlmaWVyIHJlbWFpbnMgd3JhcHBlZC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCA9IHtiaW5kaW5nczogbmV3IE1hcCgpLCBjbGFzc2VzOiBuZXcgTWFwKCksIGVycm9yczogbmV3IE1hcCgpLCBlcnJvck5hbWVzOiBuZXcgTWFwKCksIGZ1bmN0aW9uczogbmV3IE1hcCgpLCByZWNvcmROYW1lczogbmV3IE1hcCgpLCByZWNvcmRzOiBuZXcgTWFwKCksIHZhbHVlUmVjb3JkTmFtZXM6IG5ldyBNYXAoKX0sIGV4cGVjdGVkVHlwZSwgcHJlc2VydmVPcHRpb25hbCA9IGZhbHNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJiBub2RlLm5hbWUgPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJ1bmRlZmluZWQgYWJzZW5jZSB2YWx1ZVwiLCBsb2NhdGlvbilcbiAgfVxuXG4gIGlmIChleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJPcHRpb25hbFR5cGVcIikge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJOdWxsTGl0ZXJhbFwiKSB7XG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiT3B0aW9uYWxOb25lXCIpLCBsb2NhdGlvbn0sIHthYnNlbmNlOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChrbm93bkV4cHJlc3Npb25UeXBlKG5vZGUsIGNvbnRleHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gY29udmVydEV4cHJlc3Npb24obm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICB9XG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiT3B0aW9uYWxTb21lXCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICB2YWx1ZTogY29udmVydEV4cHJlc3Npb24obm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGV4cGVjdGVkVHlwZS52YWx1ZVR5cGUpXG4gICAgfSwge3NvbWU6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJOdWxsTGl0ZXJhbFwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibnVsbCBvdXRzaWRlIGFuIGV4cGxpY2l0IG9wdGlvbmFsIGNvbnRleHRcIiwgbG9jYXRpb24pXG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIlRTTm9uTnVsbEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSBjb252ZXJ0RXhwcmVzc2lvbihub2RlLmV4cHJlc3Npb24sIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuXG4gICAgaWYgKGxhbmd1YWdlICE9IFwidHlwZXNjcmlwdFwiIHx8IGV4cHJlc3Npb24ua2luZCAhPSBcIk1hcExvb2t1cEV4cHJlc3Npb25cIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcIm5vbi1udWxsIGFzc2VydGlvbiBvdGhlciB0aGFuIE1hcC5nZXQgcmVzdWx0XCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBleHByZXNzaW9uLmxvY2F0aW9uID0gbG9jYXRpb25cbiAgICByZXR1cm4gZXhwcmVzc2lvblxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIklkZW50aWZpZXJcIikge1xuICAgIGNvbnN0IGlkZW50aWZpZXIgPSB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sIG5hbWU6IG5vZGUubmFtZX0sIHtcbiAgICAgIG5hbWU6IGlkZW50aWZpZXJMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pXG5cbiAgICBpZiAoIXByZXNlcnZlT3B0aW9uYWwgJiYgY29udGV4dC5iaW5kaW5ncy5nZXQobm9kZS5uYW1lKT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiKSB7XG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiT3B0aW9uYWxVbndyYXBcIiksIGxvY2F0aW9uLCBvcGVyYW5kOiBpZGVudGlmaWVyfSwge3Vud3JhcDogbG9jYXRpb259KVxuICAgIH1cblxuICAgIHJldHVybiBpZGVudGlmaWVyXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiVGhpc0V4cHJlc3Npb25cIikge1xuICAgIGlmICghY29udGV4dC5jdXJyZW50Q2xhc3MpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJyZWNlaXZlciBvdXRzaWRlIGEgcmVmZXJlbmNlIGNsYXNzXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2NsYXNzSWQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoY29udGV4dC5jdXJyZW50Q2xhc3MuaWQpLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJSZWNlaXZlckV4cHJlc3Npb25cIiksIGxvY2F0aW9ufSxcbiAgICAgIHtyZWNlaXZlcjogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIk51bWVyaWNMaXRlcmFsXCIpIHtcbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKG5vZGUudmFsdWUpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibm9uLXNhZmUgaW50ZWdlciBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkludGVnZXJMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IG5vZGUudmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkJvb2xlYW5MaXRlcmFsXCIpIHtcbiAgICBpZiAodHlwZW9mIG5vZGUudmFsdWUgIT0gXCJib29sZWFuXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJpbnZhbGlkIGJvb2xlYW4gbGl0ZXJhbCB2YWx1ZVwiLCBsb2NhdGlvbilcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCb29sZWFuTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBub2RlLnZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJTdHJpbmdMaXRlcmFsXCIpIHtcbiAgICBpZiAodHlwZW9mIG5vZGUudmFsdWUgIT0gXCJzdHJpbmdcIiB8fCAhaGFzT25seVVuaWNvZGVTY2FsYXJzKG5vZGUudmFsdWUpKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiaW52YWxpZCBVbmljb2RlIHN0cmluZyBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IG5vZGUudmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkFycmF5RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3QgZWxlbWVudFR5cGUgPSBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJMaXN0VHlwZVwiID8gZXhwZWN0ZWRUeXBlLmVsZW1lbnRUeXBlIDogdW5kZWZpbmVkXG4gICAgY29uc3QgZWxlbWVudHMgPSBub2RlLmVsZW1lbnRzLm1hcCgoZWxlbWVudCwgaW5kZXgpID0+IHtcbiAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcInNwYXJzZSBhcnJheSBob2xlXCIsIGFycmF5SG9sZUxvY2F0aW9uKG5vZGUsIGluZGV4LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIGlmIChlbGVtZW50LnR5cGUgPT0gXCJTcHJlYWRFbGVtZW50XCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJhcnJheSBzcHJlYWRcIiwgbm9kZUxvY2F0aW9uKGVsZW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gICAgICByZXR1cm4gY29udmVydEV4cHJlc3Npb24oZWxlbWVudCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGVsZW1lbnRUeXBlKVxuICAgIH0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7ZWxlbWVudHMsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxpc3RMaXRlcmFsXCIpLCBsb2NhdGlvbn0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiTmV3RXhwcmVzc2lvblwiICYmIG5vZGUuY2FsbGVlLnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiYgbm9kZS5jYWxsZWUubmFtZSA9PSBcIk1hcFwiKSB7XG4gICAgaWYgKCFuYXRpdmVNYXBBdmFpbGFibGUoY29udGV4dCkpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJzaGFkb3dlZCBNYXAgY29uc3RydWN0b3JcIiwgaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuY2FsbGVlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgaWYgKGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIlJlY29yZFR5cGVcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcIk1hcCB1c2VkIGFzIGEgc3RydWN0dXJhbCByZWNvcmQgc3Vic3RpdHV0ZVwiLCBsb2NhdGlvbilcbiAgICBpZiAobm9kZS50eXBlQXJndW1lbnRzIHx8IG5vZGUudHlwZVBhcmFtZXRlcnMgfHwgbm9kZS5hcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImdlbmVyaWMgb3IgaW52YWxpZCBNYXAgY29uc3RydWN0aW9uXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBpbml0aWFsaXplciA9IG5vZGUuYXJndW1lbnRzWzBdXG5cbiAgICBpZiAoIWluaXRpYWxpemVyKSByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBlbnRyaWVzOiBbXSxcbiAgICAgIGtpbmQ6IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCJcbiAgICAgICAgPyAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJPcmRlcmVkTWFwTGl0ZXJhbFwiKVxuICAgICAgICA6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1hcExpdGVyYWxcIiksXG4gICAgICBsb2NhdGlvblxuICAgIH0sIHtsaXRlcmFsOiBsb2NhdGlvbn0pXG4gICAgaWYgKGluaXRpYWxpemVyLnR5cGUgPT0gXCJTcHJlYWRFbGVtZW50XCIgfHwgaW5pdGlhbGl6ZXIudHlwZSA9PSBcIkFyZ3VtZW50UGxhY2Vob2xkZXJcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBpbml0aWFsaXplci50eXBlLCBub2RlTG9jYXRpb24oaW5pdGlhbGl6ZXIsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBpZiAoaW5pdGlhbGl6ZXIudHlwZSAhPSBcIkFycmF5RXhwcmVzc2lvblwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiTWFwIGluaXRpYWxpemVyIG90aGVyIHRoYW4gYW4gZW50cnkgYXJyYXlcIiwgbm9kZUxvY2F0aW9uKGluaXRpYWxpemVyLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgdmFsdWVUeXBlID0gZXhwZWN0ZWRUeXBlPy5raW5kID09IFwiTWFwVHlwZVwiIHx8IGV4cGVjdGVkVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCJcbiAgICAgID8gZXhwZWN0ZWRUeXBlLnZhbHVlVHlwZSA6IHVuZGVmaW5lZFxuICAgIGNvbnN0IGVudHJpZXMgPSBpbml0aWFsaXplci5lbGVtZW50cy5tYXAoKGVsZW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoIWVsZW1lbnQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJzcGFyc2UgbWFwIGluaXRpYWxpemVyXCIsIGFycmF5SG9sZUxvY2F0aW9uKGluaXRpYWxpemVyLCBpbmRleCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBpZiAoZWxlbWVudC50eXBlID09IFwiU3ByZWFkRWxlbWVudFwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibWFwIHNwcmVhZFwiLCBub2RlTG9jYXRpb24oZWxlbWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBpZiAoZWxlbWVudC50eXBlICE9IFwiQXJyYXlFeHByZXNzaW9uXCIgfHwgZWxlbWVudC5lbGVtZW50cy5sZW5ndGggIT0gMikge1xuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiTWFwIGVudHJ5IG90aGVyIHRoYW4gYSBrZXkvdmFsdWUgcGFpclwiLCBub2RlTG9jYXRpb24oZWxlbWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG4gICAgICBjb25zdCBba2V5LCB2YWx1ZV0gPSBlbGVtZW50LmVsZW1lbnRzXG5cbiAgICAgIGlmICgha2V5KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwic3BhcnNlIG1hcCBrZXlcIiwgYXJyYXlIb2xlTG9jYXRpb24oZWxlbWVudCwgMCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBpZiAoIXZhbHVlKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwic3BhcnNlIG1hcCB2YWx1ZVwiLCBhcnJheUhvbGVMb2NhdGlvbihlbGVtZW50LCAxLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIGlmIChrZXkudHlwZSA9PSBcIlNwcmVhZEVsZW1lbnRcIiB8fCB2YWx1ZS50eXBlID09IFwiU3ByZWFkRWxlbWVudFwiKSB7XG4gICAgICAgIGNvbnN0IHNwcmVhZCA9IGtleS50eXBlID09IFwiU3ByZWFkRWxlbWVudFwiID8ga2V5IDogdmFsdWVcblxuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibWFwIGVudHJ5IHNwcmVhZFwiLCBub2RlTG9jYXRpb24oc3ByZWFkLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIH1cbiAgICAgIGlmIChrZXkudHlwZSAhPSBcIlN0cmluZ0xpdGVyYWxcIikge1xuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibWFwIGtleSBvdGhlciB0aGFuIGEgc3RyaW5nIGxpdGVyYWxcIiwgbm9kZUxvY2F0aW9uKGtleSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG4gICAgICBjb25zdCBrZXlFeHByZXNzaW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TdHJpbmdMaXRlcmFsfSAqLyAoXG4gICAgICAgIGNvbnZlcnRFeHByZXNzaW9uKGtleSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gICAgICApXG5cbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAga2V5OiBrZXlFeHByZXNzaW9uLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNYXBFbnRyeVwiKSxcbiAgICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihlbGVtZW50LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgdmFsdWU6IGNvbnZlcnRFeHByZXNzaW9uKHZhbHVlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCwgdmFsdWVUeXBlKVxuICAgICAgfSwge1xuICAgICAgICBrZXk6IGtleUV4cHJlc3Npb24ubG9jYXRpb24sXG4gICAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKGVsZW1lbnQsIFwiLFwiLCBrZXkuZW5kID8/IGVsZW1lbnQuc3RhcnQgPz8gMCwgdmFsdWUuc3RhcnQgPz8gZWxlbWVudC5lbmQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGVudHJpZXMsXG4gICAgICBraW5kOiBleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJPcmRlcmVkTWFwVHlwZVwiXG4gICAgICAgID8gLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiT3JkZXJlZE1hcExpdGVyYWxcIilcbiAgICAgICAgOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNYXBMaXRlcmFsXCIpLFxuICAgICAgbG9jYXRpb25cbiAgICB9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIk5ld0V4cHJlc3Npb25cIiAmJiBub2RlLmNhbGxlZS50eXBlID09IFwiSWRlbnRpZmllclwiICYmIGNvbnRleHQudmFsdWVSZWNvcmROYW1lcy5oYXMobm9kZS5jYWxsZWUubmFtZSkpIHtcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSAqLyAoY29udGV4dC52YWx1ZVJlY29yZE5hbWVzLmdldChub2RlLmNhbGxlZS5uYW1lKSlcbiAgICBpZiAoZGVjbGFyYXRpb24ua2luZCA9PSBcIkNsYXNzRGVjbGFyYXRpb25cIikge1xuICAgICAgaWYgKG5vZGUudHlwZUFyZ3VtZW50cyB8fCBub2RlLnR5cGVQYXJhbWV0ZXJzKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiZ2VuZXJpYyByZWZlcmVuY2UgY29uc3RydWN0aW9uXCIsIGxvY2F0aW9uKVxuICAgICAgY29uc3QgYXJndW1lbnRzXyA9IG5vZGUuYXJndW1lbnRzLm1hcCgoYXJndW1lbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChhcmd1bWVudC50eXBlID09IFwiU3ByZWFkRWxlbWVudFwiIHx8IGFyZ3VtZW50LnR5cGUgPT0gXCJBcmd1bWVudFBsYWNlaG9sZGVyXCIpIHtcbiAgICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGFyZ3VtZW50LnR5cGUsIG5vZGVMb2NhdGlvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LCBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzW2luZGV4XT8udHlwZSlcbiAgICAgIH0pXG4gICAgICBjb25zdCBjbGFzc0xvY2F0aW9uID0gaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuY2FsbGVlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7YXJndW1lbnRzOiBhcmd1bWVudHNfLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJSZWZlcmVuY2VDb25zdHJ1Y3Rpb25cIiksIGxvY2F0aW9uLFxuICAgICAgICByZWZlcmVuY2U6IGRlY2xhcmF0aW9uLm93bmVyc2hpcD8ua2luZCA9PSBcIm93bmVkUmVzb3VyY2VcIlxuICAgICAgICAgID8gb3duZWRSZWZlcmVuY2VUeXBlKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBjbGFzc0xvY2F0aW9uKVxuICAgICAgICAgIDogcmVmZXJlbmNlVHlwZSgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgY2xhc3NMb2NhdGlvbil9LCB7Y2xhc3M6IGNsYXNzTG9jYXRpb259KVxuICAgIH1cbiAgICBjb25zdCBzb3VyY2VBcmd1bWVudHMgPSBub2RlLnR5cGVBcmd1bWVudHM/LnBhcmFtcyA/PyBub2RlLnR5cGVQYXJhbWV0ZXJzPy5wYXJhbXNcbiAgICBjb25zdCB0eXBlQXJndW1lbnRzID0gc291cmNlQXJndW1lbnRzPy5tYXAoKC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlRTVHlwZX0gKi8gYXJndW1lbnQpID0+IGNvbnZlcnRUeXBlU2NyaXB0VmFsdWVUeXBlTm9kZShcbiAgICAgIGFyZ3VtZW50LFxuICAgICAgYFJlY29yZCAnJHtkZWNsYXJhdGlvbi5uYW1lfScgYXBwbGljYXRpb25gLCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dC5yZWNvcmROYW1lcywgY29udGV4dC50eXBlUGFyYW1ldGVyc1xuICAgICkpID8/IChleHBlY3RlZFR5cGU/LmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIgJiYgZXhwZWN0ZWRUeXBlLmRlY2xhcmF0aW9uSWQgPT0gZGVjbGFyYXRpb24uaWQgPyBleHBlY3RlZFR5cGUuYXJndW1lbnRzIDogdW5kZWZpbmVkKVxuICAgIGNvbnN0IGFyZ3VtZW50c18gPSBub2RlLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGFyZ3VtZW50LnR5cGUgPT0gXCJTcHJlYWRFbGVtZW50XCIgfHwgYXJndW1lbnQudHlwZSA9PSBcIkFyZ3VtZW50UGxhY2Vob2xkZXJcIikge1xuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGFyZ3VtZW50LnR5cGUsIG5vZGVMb2NhdGlvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsXG4gICAgICAgIGluc3RhbnRpYXRlZFJlY29yZEZpZWxkVHlwZShkZWNsYXJhdGlvbiwgdHlwZUFyZ3VtZW50cywgaW5kZXgpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBhcmd1bWVudHM6IGFyZ3VtZW50c18sXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJSZWNvcmRDb25zdHJ1Y3Rpb25cIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIHJlY29yZDogcmVjb3JkVHlwZSgvKiogQHR5cGUge3N0cmluZ30gKi8gKGRlY2xhcmF0aW9uLmlkKSwgaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuY2FsbGVlLCBmaWxlbmFtZSwgc291cmNlKSwgdHlwZUFyZ3VtZW50cylcbiAgICB9LCB7cmVjb3JkOiBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5jYWxsZWUsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgJiYgIW5vZGUub3B0aW9uYWwgJiYgbm9kZS5vYmplY3QudHlwZSAhPSBcIlN1cGVyXCIpIHtcbiAgICBpZiAoIW5vZGUuY29tcHV0ZWQgJiYgbm9kZS5vYmplY3QudHlwZSA9PSBcIlRoaXNFeHByZXNzaW9uXCIgJiYgY29udGV4dC5jdXJyZW50Q2xhc3MpIHtcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLklkZW50aWZpZXIgfCB1bmRlZmluZWR9ICovXG4gICAgICBsZXQgcHJvcGVydHlcblxuICAgICAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiICYmIG5vZGUucHJvcGVydHkudHlwZSA9PSBcIlByaXZhdGVOYW1lXCIpIHByb3BlcnR5ID0gbm9kZS5wcm9wZXJ0eS5pZFxuICAgICAgaWYgKGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiICYmIG5vZGUucHJvcGVydHkudHlwZSA9PSBcIklkZW50aWZpZXJcIikgcHJvcGVydHkgPSBub2RlLnByb3BlcnR5XG4gICAgICBpZiAoIXByb3BlcnR5KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibm9uY2Fub25pY2FsIHByaXZhdGUgaW5zdGFuY2UgZmllbGQgYWNjZXNzXCIsIGxvY2F0aW9uKVxuICAgICAgY29uc3QgZmllbGQgPSBjb250ZXh0LmN1cnJlbnRDbGFzcy5maWVsZHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PSBwcm9wZXJ0eS5uYW1lKVxuXG4gICAgICBpZiAoIWZpZWxkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGB1bmtub3duIHByaXZhdGUgZmllbGQgJyR7cHJvcGVydHkubmFtZX0nYCwgaWRlbnRpZmllckxvY2F0aW9uKHByb3BlcnR5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtmaWVsZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChmaWVsZC5pZCksIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlByaXZhdGVGaWVsZFJlYWRcIiksIGxvY2F0aW9uLFxuICAgICAgICByZWNlaXZlcjogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNlaXZlckV4cHJlc3Npb259ICovIChcbiAgICAgICAgICBjb252ZXJ0RXhwcmVzc2lvbihub2RlLm9iamVjdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpKX0sIHttZW1iZXI6IGlkZW50aWZpZXJMb2NhdGlvbihwcm9wZXJ0eSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICAgIH1cbiAgICBpZiAoa25vd25WYWx1ZUV4cHJlc3Npb25UeXBlKG5vZGUub2JqZWN0LCBjb250ZXh0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSk/LmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJwcml2YXRlIHJlZmVyZW5jZS1jbGFzcyBmaWVsZCBhY2Nlc3NcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGlmICghbm9kZS5jb21wdXRlZCAmJiBub2RlLm9iamVjdC50eXBlID09IFwiSWRlbnRpZmllclwiICYmIG5vZGUucHJvcGVydHkudHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJlxuICAgICAgbm9kZS5wcm9wZXJ0eS5uYW1lID09IFwibWVzc2FnZVwiICYmIGNvbnRleHQuYmluZGluZ3MuZ2V0KG5vZGUub2JqZWN0Lm5hbWUpPy5raW5kID09IFwiRXJyb3JUeXBlXCIpIHtcbiAgICAgIGNvbnN0IHJlY2VpdmVyTG9jYXRpb24gPSBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5vYmplY3QsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JNZXNzYWdlUmVhZFwiKSxcbiAgICAgICAgbG9jYXRpb24sXG4gICAgICAgIHJlY2VpdmVyOiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJJZGVudGlmaWVyRXhwcmVzc2lvblwiKSwgbG9jYXRpb246IHJlY2VpdmVyTG9jYXRpb24sIG5hbWU6IG5vZGUub2JqZWN0Lm5hbWV9LCB7XG4gICAgICAgICAgbmFtZTogcmVjZWl2ZXJMb2NhdGlvblxuICAgICAgICB9KVxuICAgICAgfSwge21lbWJlcjogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUucHJvcGVydHksIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG4gICAgaWYgKG5vZGUuY29tcHV0ZWQpIHtcbiAgICAgIGlmIChrbm93blZhbHVlRXhwcmVzc2lvblR5cGUobm9kZS5vYmplY3QsIGNvbnRleHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKT8ua2luZCA9PSBcIlJlY29yZFR5cGVcIikge1xuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiY29tcHV0ZWQgcmVjb3JkIG1lbWJlciBhY2Nlc3NcIiwgbm9kZUxvY2F0aW9uKG5vZGUucHJvcGVydHksIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUucHJvcGVydHkudHlwZSA9PSBcIlByaXZhdGVOYW1lXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS5wcm9wZXJ0eS50eXBlLCBsb2NhdGlvbilcblxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBjb2xsZWN0aW9uOiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLm9iamVjdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBpbmRleDogY29udmVydEV4cHJlc3Npb24obm9kZS5wcm9wZXJ0eSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJMaXN0SW5kZXhFeHByZXNzaW9uXCIpLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgdG90YWxpdHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcInByb3ZlblwiKVxuICAgICAgfSwge1xuICAgICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihub2RlLCBcIltcIiwgbm9kZS5vYmplY3QuZW5kID8/IG5vZGUuc3RhcnQgPz8gMCwgbm9kZS5wcm9wZXJ0eS5zdGFydCA/PyBub2RlLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgICAgfSlcbiAgICB9XG4gICAgaWYgKG5vZGUucHJvcGVydHkudHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJiBbXCJsZW5ndGhcIiwgXCJzaXplXCJdLmluY2x1ZGVzKG5vZGUucHJvcGVydHkubmFtZSkpIHtcbiAgICAgIGNvbnN0IHJlY2VpdmVyVHlwZSA9IGtub3duVmFsdWVFeHByZXNzaW9uVHlwZShub2RlLm9iamVjdCwgY29udGV4dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICAgIGlmIChyZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJSZWNvcmRUeXBlXCIpIHtcbiAgICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICAgIGZpZWxkOiBub2RlLnByb3BlcnR5Lm5hbWUsXG4gICAgICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTWVtYmVyUmVhZFwiKSxcbiAgICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgICByZWNlaXZlcjogY29udmVydEV4cHJlc3Npb24obm9kZS5vYmplY3QsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgICAgICB9LCB7bWVtYmVyOiBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5wcm9wZXJ0eSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICAgICAgfVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBjb2xsZWN0aW9uOiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLm9iamVjdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpLFxuICAgICAgICBjb2xsZWN0aW9uS2luZDogLyoqIEB0eXBlIHtcImxpc3RcIiB8IFwibWFwXCJ9ICovIChub2RlLnByb3BlcnR5Lm5hbWUgPT0gXCJsZW5ndGhcIiA/IFwibGlzdFwiIDogXCJtYXBcIiksXG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkNvbGxlY3Rpb25TaXplRXhwcmVzc2lvblwiKSxcbiAgICAgICAgbG9jYXRpb25cbiAgICAgIH0sIHtvcGVyYXRvcjogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUucHJvcGVydHksIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG4gICAgaWYgKG5vZGUucHJvcGVydHkudHlwZSA9PSBcIklkZW50aWZpZXJcIikge1xuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgICBmaWVsZDogbm9kZS5wcm9wZXJ0eS5uYW1lLFxuICAgICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNZW1iZXJSZWFkXCIpLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgcmVjZWl2ZXI6IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUub2JqZWN0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICAgIH0sIHttZW1iZXI6IGlkZW50aWZpZXJMb2NhdGlvbihub2RlLnByb3BlcnR5LCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgfVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIlRlbXBsYXRlTGl0ZXJhbFwiKSB7XG4gICAgaWYgKG5vZGUuZXhwcmVzc2lvbnMubGVuZ3RoID4gMCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImludGVycG9sYXRlZCBzdHJpbmdcIiwgbG9jYXRpb24pXG5cbiAgICBjb25zdCBxdWFzaSA9IG5vZGUucXVhc2lzWzBdXG5cbiAgICBpZiAodHlwZW9mIHF1YXNpLnZhbHVlLmNvb2tlZCAhPSBcInN0cmluZ1wiIHx8ICFoYXNPbmx5VW5pY29kZVNjYWxhcnMocXVhc2kudmFsdWUuY29va2VkKSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImludmFsaWQgVW5pY29kZSBzdHJpbmcgbGl0ZXJhbFwiLCBsb2NhdGlvbilcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiU3RyaW5nTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBxdWFzaS52YWx1ZS5jb29rZWR9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiICYmIFtcIiFcIiwgXCItXCJdLmluY2x1ZGVzKG5vZGUub3BlcmF0b3IpKSB7XG4gICAgY29uc3Qgb3BlcmFuZCA9IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUuYXJndW1lbnQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgIGNvbnN0IHNlbWFudGljID0gd2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLFxuICAgICAgbG9jYXRpb24sXG4gICAgICBvcGVyYW5kXG4gICAgfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24obm9kZSwgbm9kZS5vcGVyYXRvciwgbm9kZS5zdGFydCA/PyAwLCBub2RlLmFyZ3VtZW50LnN0YXJ0ID8/IG5vZGUuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSksIG5vZGUub3BlcmF0b3IgPT0gXCIhXCIgPyBcIk5vdFwiIDogXCJOZWdhdGVcIilcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChzZW1hbnRpYykpXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiTG9naWNhbEV4cHJlc3Npb25cIiAmJiBbXCImJlwiLCBcInx8XCJdLmluY2x1ZGVzKG5vZGUub3BlcmF0b3IpKSB7XG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IFwiQmluYXJ5RXhwcmVzc2lvblwiLFxuICAgICAgbGVmdDogY29udmVydEV4cHJlc3Npb24obm9kZS5sZWZ0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIHJpZ2h0OiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLnJpZ2h0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICB9LCB7XG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihub2RlLCBub2RlLm9wZXJhdG9yLCBub2RlLmxlZnQuZW5kID8/IG5vZGUuc3RhcnQgPz8gMCwgbm9kZS5yaWdodC5zdGFydCA/PyBub2RlLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pLCBub2RlLm9wZXJhdG9yID09IFwiJiZcIiA/IFwiQW5kXCIgOiBcIk9yXCIpXG5cbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FeHByZXNzaW9ufSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoc2VtYW50aWMpKVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIiAmJiBub2RlLm9wZXJhdG9yID09IFwiIT09XCIgJiYgbm9kZS5sZWZ0LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiZcbiAgICBub2RlLnJpZ2h0LnR5cGUgPT0gXCJOdWxsTGl0ZXJhbFwiKSB7XG4gICAgY29uc3Qgb3BlcmFuZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWRlbnRpZmllckV4cHJlc3Npb259ICovIChcbiAgICAgIGNvbnZlcnRFeHByZXNzaW9uKG5vZGUubGVmdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICApXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiT3B0aW9uYWxJc1ByZXNlbnRcIiksIGxvY2F0aW9uLCBvcGVyYW5kfSwge1xuICAgICAgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24obm9kZSwgbm9kZS5vcGVyYXRvciwgbm9kZS5sZWZ0LmVuZCA/PyBub2RlLnN0YXJ0ID8/IDAsIG5vZGUucmlnaHQuc3RhcnQgPz8gbm9kZS5lbmQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIiAmJiBiYWJlbEJpbmFyeU9wZXJhdGlvbnMuaGFzKG5vZGUub3BlcmF0b3IpKSB7XG4gICAgaWYgKG5vZGUubGVmdC50eXBlID09IFwiUHJpdmF0ZU5hbWVcIikgdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIG5vZGUubGVmdC50eXBlLCBsb2NhdGlvbilcblxuICAgIGNvbnN0IGxlZnQgPSBjb252ZXJ0RXhwcmVzc2lvbihub2RlLmxlZnQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgIGNvbnN0IHJpZ2h0ID0gY29udmVydEV4cHJlc3Npb24obm9kZS5yaWdodCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG5cbiAgICBjb25zdCBzZW1hbnRpYyA9IHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogXCJCaW5hcnlFeHByZXNzaW9uXCIsXG4gICAgICBsZWZ0LFxuICAgICAgbG9jYXRpb24sXG4gICAgICByaWdodFxuICAgIH0sIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKG5vZGUsIG5vZGUub3BlcmF0b3IsIG5vZGUubGVmdC5lbmQgPz8gbm9kZS5zdGFydCA/PyAwLCBub2RlLnJpZ2h0LnN0YXJ0ID8/IG5vZGUuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSksIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCIpLkFkYXB0ZWRPcGVyYXRpb259ICovIChiYWJlbEJpbmFyeU9wZXJhdGlvbnMuZ2V0KG5vZGUub3BlcmF0b3IpKSlcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChzZW1hbnRpYykpXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiQmluYXJ5RXhwcmVzc2lvblwiICYmIFtcIj09XCIsIFwiIT1cIl0uaW5jbHVkZXMobm9kZS5vcGVyYXRvcikpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGBjb2VyY2l2ZSBlcXVhbGl0eSAke25vZGUub3BlcmF0b3J9YCwgbG9jYXRpb24pXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiBub2RlLmNhbGxlZS50eXBlID09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgaWYgKG5vZGUub3B0aW9uYWwgfHwgbm9kZS5jYWxsZWUub3B0aW9uYWwgfHwgbm9kZS50eXBlQXJndW1lbnRzIHx8IG5vZGUudHlwZVBhcmFtZXRlcnMpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJvcHRpb25hbCBvciBnZW5lcmljIGNhbGxcIiwgbG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHNpZ25hdHVyZSA9IGNvbnRleHQuZnVuY3Rpb25zLmdldChub2RlLmNhbGxlZS5uYW1lKVxuICAgIGNvbnN0IGFyZ3VtZW50c18gPSBub2RlLmFyZ3VtZW50cy5tYXAoKGFyZ3VtZW50LCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGFyZ3VtZW50LnR5cGUgPT0gXCJTcHJlYWRFbGVtZW50XCIgfHwgYXJndW1lbnQudHlwZSA9PSBcIkFyZ3VtZW50UGxhY2Vob2xkZXJcIikge1xuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGFyZ3VtZW50LnR5cGUsIG5vZGVMb2NhdGlvbihhcmd1bWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG5cbiAgICAgIHJldHVybiBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHNpZ25hdHVyZT8ucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUsXG4gICAgICAgIHByZXNlcnZlc0dlbmVyaWNPcHRpb25hbEV2aWRlbmNlKHNpZ25hdHVyZSwgaW5kZXgpKVxuICAgIH0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7YXJndW1lbnRzOiBhcmd1bWVudHNfLCBjYWxsZWU6IG5vZGUuY2FsbGVlLm5hbWUsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkNhbGxFeHByZXNzaW9uXCIpLCBsb2NhdGlvbn0sIHtcbiAgICAgIGNhbGxlZTogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuY2FsbGVlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiAhbm9kZS5vcHRpb25hbCAmJiAhbm9kZS50eXBlQXJndW1lbnRzICYmICFub2RlLnR5cGVQYXJhbWV0ZXJzICYmXG4gICAgbm9kZS5jYWxsZWUudHlwZSA9PSBcIk1lbWJlckV4cHJlc3Npb25cIiAmJiAhbm9kZS5jYWxsZWUuY29tcHV0ZWQgJiYgIW5vZGUuY2FsbGVlLm9wdGlvbmFsICYmXG4gICAgbm9kZS5jYWxsZWUub2JqZWN0LnR5cGUgIT0gXCJTdXBlclwiICYmIG5vZGUuY2FsbGVlLnByb3BlcnR5LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIpIHtcbiAgICBjb25zdCByZWNlaXZlclR5cGUgPSBrbm93blZhbHVlRXhwcmVzc2lvblR5cGUobm9kZS5jYWxsZWUub2JqZWN0LCBjb250ZXh0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChyZWNlaXZlclR5cGU/LmtpbmQgPT0gXCJSZWZlcmVuY2VUeXBlXCIgfHwgcmVjZWl2ZXJUeXBlPy5raW5kID09IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIpIHtcbiAgICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gY29udGV4dC5jbGFzc2VzLmdldChyZWNlaXZlclR5cGUuZGVjbGFyYXRpb25JZClcbiAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBub2RlLmNhbGxlZS5wcm9wZXJ0eS5uYW1lXG4gICAgICBjb25zdCBtZXRob2QgPSBkZWNsYXJhdGlvbj8ubWV0aG9kcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5uYW1lID09IG1ldGhvZE5hbWUpXG4gICAgICBjb25zdCBhcmd1bWVudHNfID0gbm9kZS5hcmd1bWVudHMubWFwKChhcmd1bWVudCwgaW5kZXgpID0+IHtcbiAgICAgICAgaWYgKGFyZ3VtZW50LnR5cGUgPT0gXCJTcHJlYWRFbGVtZW50XCIgfHwgYXJndW1lbnQudHlwZSA9PSBcIkFyZ3VtZW50UGxhY2Vob2xkZXJcIikge1xuICAgICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgYXJndW1lbnQudHlwZSwgbm9kZUxvY2F0aW9uKGFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjb252ZXJ0RXhwcmVzc2lvbihhcmd1bWVudCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIG1ldGhvZD8ucGFyYW1ldGVyc1tpbmRleF0/LnR5cGUpXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7YXJndW1lbnRzOiBhcmd1bWVudHNfLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNZXRob2RDYWxsRXhwcmVzc2lvblwiKSwgbG9jYXRpb24sXG4gICAgICAgIG1ldGhvZDogbWV0aG9kPy5pZCA/PyBub2RlLmNhbGxlZS5wcm9wZXJ0eS5uYW1lLFxuICAgICAgICByZWNlaXZlcjogY29udmVydEV4cHJlc3Npb24obm9kZS5jYWxsZWUub2JqZWN0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCl9LFxuICAgICAge21lbWJlcjogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuY2FsbGVlLnByb3BlcnR5LCBmaWxlbmFtZSwgc291cmNlKX0pXG4gICAgfVxuICB9XG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgIW5vZGUub3B0aW9uYWwgJiYgIW5vZGUudHlwZUFyZ3VtZW50cyAmJiAhbm9kZS50eXBlUGFyYW1ldGVycyAmJlxuICAgIG5vZGUuY2FsbGVlLnR5cGUgPT0gXCJNZW1iZXJFeHByZXNzaW9uXCIgJiYgIW5vZGUuY2FsbGVlLmNvbXB1dGVkICYmICFub2RlLmNhbGxlZS5vcHRpb25hbCAmJlxuICAgIG5vZGUuY2FsbGVlLm9iamVjdC50eXBlICE9IFwiU3VwZXJcIiAmJiBub2RlLmNhbGxlZS5wcm9wZXJ0eS50eXBlID09IFwiSWRlbnRpZmllclwiICYmXG4gICAgbm9kZS5jYWxsZWUucHJvcGVydHkubmFtZSA9PSBcImdldFwiKSB7XG4gICAgaWYgKG5vZGUuYXJndW1lbnRzLmxlbmd0aCAhPSAxKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiTWFwLmdldCBhcmd1bWVudCBjb3VudFwiLCBsb2NhdGlvbilcbiAgICBjb25zdCBrZXkgPSBub2RlLmFyZ3VtZW50c1swXVxuXG4gICAgaWYgKGtleS50eXBlID09IFwiU3ByZWFkRWxlbWVudFwiIHx8IGtleS50eXBlID09IFwiQXJndW1lbnRQbGFjZWhvbGRlclwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGtleS50eXBlLCBub2RlTG9jYXRpb24oa2V5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBjb2xsZWN0aW9uOiBjb252ZXJ0RXhwcmVzc2lvbihub2RlLmNhbGxlZS5vYmplY3QsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICAgIGtleTogY29udmVydEV4cHJlc3Npb24oa2V5LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJNYXBMb29rdXBFeHByZXNzaW9uXCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICB0b3RhbGl0eTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwicHJvdmVuXCIpXG4gICAgfSwge29wZXJhdG9yOiBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5jYWxsZWUucHJvcGVydHksIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfVxuXG4gIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBsb2NhdGlvbilcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBvbmx5IGV4cHJlc3Npb24gcmVzdWx0IHR5cGVzIGFscmVhZHkgZXN0YWJsaXNoZWQgYnkgZXhwbGljaXQgbW9kdWxlXG4gKiBzaWduYXR1cmVzIGFuZCBjb2xsZWN0aW9uIGJpbmRpbmdzLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBhcnNlci1vd25lZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtKYXZhU2NyaXB0Q29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnRleHQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JUeXBlIHwgdW5kZWZpbmVkfSBLbm93biByZXN1bHQgdHlwZS5cbiAqL1xuZnVuY3Rpb24ga25vd25FeHByZXNzaW9uVHlwZShub2RlLCBjb250ZXh0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAobm9kZS50eXBlID09IFwiVFNOb25OdWxsRXhwcmVzc2lvblwiKSByZXR1cm4ga25vd25FeHByZXNzaW9uVHlwZShub2RlLmV4cHJlc3Npb24sIGNvbnRleHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKVxuICBpZiAobm9kZS50eXBlID09IFwiSWRlbnRpZmllclwiKSByZXR1cm4gY29udGV4dC5iaW5kaW5ncy5nZXQobm9kZS5uYW1lKVxuICBpZiAobm9kZS50eXBlID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiBub2RlLmNhbGxlZS50eXBlID09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgY29uc3Qgc2lnbmF0dXJlID0gY29udGV4dC5mdW5jdGlvbnMuZ2V0KG5vZGUuY2FsbGVlLm5hbWUpXG5cbiAgICBpZiAoc2lnbmF0dXJlKSByZXR1cm4ga25vd25DYWxsUmV0dXJuVHlwZShzaWduYXR1cmUsIG5vZGUuYXJndW1lbnRzLm1hcCgoYXJndW1lbnQpID0+XG4gICAgICBhcmd1bWVudC50eXBlID09IFwiU3ByZWFkRWxlbWVudFwiIHx8IGFyZ3VtZW50LnR5cGUgPT0gXCJBcmd1bWVudFBsYWNlaG9sZGVyXCJcbiAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgOiBrbm93bkV4cHJlc3Npb25UeXBlKGFyZ3VtZW50LCBjb250ZXh0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSkpKVxuICB9XG4gIGlmIChub2RlLnR5cGUgPT0gXCJOZXdFeHByZXNzaW9uXCIgJiYgbm9kZS5jYWxsZWUudHlwZSA9PSBcIklkZW50aWZpZXJcIikge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gY29udGV4dC52YWx1ZVJlY29yZE5hbWVzLmdldChub2RlLmNhbGxlZS5uYW1lKVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uPy5pZCkge1xuICAgICAgaWYgKGRlY2xhcmF0aW9uLmtpbmQgPT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIpIHJldHVybiB7ZGVjbGFyYXRpb25JZDogZGVjbGFyYXRpb24uaWQsXG4gICAgICAgIGtpbmQ6IGRlY2xhcmF0aW9uLm93bmVyc2hpcD8ua2luZCA9PSBcIm93bmVkUmVzb3VyY2VcIiA/IFwiT3duZWRSZWZlcmVuY2VUeXBlXCIgOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgICAgIGNvbnN0IHNvdXJjZUFyZ3VtZW50cyA9IG5vZGUudHlwZUFyZ3VtZW50cz8ucGFyYW1zID8/IG5vZGUudHlwZVBhcmFtZXRlcnM/LnBhcmFtc1xuICAgICAgY29uc3QgdHlwZUFyZ3VtZW50cyA9IHNvdXJjZUFyZ3VtZW50cz8ubWFwKCgvKiogQHR5cGUge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5UU1R5cGV9ICovIGFyZ3VtZW50KSA9PlxuICAgICAgICBjb252ZXJ0VHlwZVNjcmlwdFZhbHVlVHlwZU5vZGUoXG4gICAgICAgICAgYXJndW1lbnQsXG4gICAgICAgICAgYFJlY29yZCAnJHtkZWNsYXJhdGlvbi5uYW1lfScgYXBwbGljYXRpb25gLFxuICAgICAgICAgIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgICBmaWxlbmFtZSxcbiAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgY29udGV4dC5yZWNvcmROYW1lcyxcbiAgICAgICAgICBjb250ZXh0LnR5cGVQYXJhbWV0ZXJzXG4gICAgICAgICkpXG5cbiAgICAgIHJldHVybiB7ZGVjbGFyYXRpb25JZDogZGVjbGFyYXRpb24uaWQsIGtpbmQ6IFwiUmVjb3JkVHlwZVwiLCAuLi4odHlwZUFyZ3VtZW50cyA/IHthcmd1bWVudHM6IHR5cGVBcmd1bWVudHN9IDoge30pfVxuICAgIH1cbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiVGhpc0V4cHJlc3Npb25cIiAmJiBjb250ZXh0LmN1cnJlbnRDbGFzcz8uaWQpIHtcbiAgICByZXR1cm4ge2RlY2xhcmF0aW9uSWQ6IGNvbnRleHQuY3VycmVudENsYXNzLmlkLCBraW5kOiBcIlJlZmVyZW5jZVR5cGVcIn1cbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiBub2RlLmNhbGxlZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmICFub2RlLmNhbGxlZS5jb21wdXRlZCAmJlxuICAgIG5vZGUuY2FsbGVlLm9iamVjdC50eXBlICE9IFwiU3VwZXJcIiAmJiBub2RlLmNhbGxlZS5wcm9wZXJ0eS50eXBlID09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgY29uc3QgcmVjZWl2ZXIgPSBrbm93blZhbHVlRXhwcmVzc2lvblR5cGUobm9kZS5jYWxsZWUub2JqZWN0LCBjb250ZXh0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChyZWNlaXZlcj8ua2luZCA9PSBcIlJlZmVyZW5jZVR5cGVcIikge1xuICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IG5vZGUuY2FsbGVlLnByb3BlcnR5Lm5hbWVcblxuICAgICAgcmV0dXJuIGNvbnRleHQuY2xhc3Nlcy5nZXQocmVjZWl2ZXIuZGVjbGFyYXRpb25JZCk/Lm1ldGhvZHMuZmluZCgobWV0aG9kKSA9PiBtZXRob2QubmFtZSA9PSBtZXRob2ROYW1lKT8ucmV0dXJuVHlwZVxuICAgIH1cbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmICFub2RlLmNvbXB1dGVkICYmIG5vZGUub2JqZWN0LnR5cGUgPT0gXCJUaGlzRXhwcmVzc2lvblwiICYmIGNvbnRleHQuY3VycmVudENsYXNzKSB7XG4gICAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiICYmIG5vZGUucHJvcGVydHkudHlwZSA9PSBcIlByaXZhdGVOYW1lXCIpIHtcbiAgICAgIGNvbnN0IG5hbWUgPSBub2RlLnByb3BlcnR5LmlkLm5hbWVcblxuICAgICAgcmV0dXJuIGNvbnRleHQuY3VycmVudENsYXNzLmZpZWxkcy5maW5kKChmaWVsZCkgPT4gZmllbGQubmFtZSA9PSBuYW1lKT8udHlwZVxuICAgIH1cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgJiYgbm9kZS5wcm9wZXJ0eS50eXBlID09IFwiSWRlbnRpZmllclwiKSB7XG4gICAgICBjb25zdCBuYW1lID0gbm9kZS5wcm9wZXJ0eS5uYW1lXG5cbiAgICAgIHJldHVybiBjb250ZXh0LmN1cnJlbnRDbGFzcy5maWVsZHMuZmluZCgoZmllbGQpID0+IGZpZWxkLm5hbWUgPT0gbmFtZSk/LnR5cGVcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcIk1lbWJlckV4cHJlc3Npb25cIiAmJiAhbm9kZS5jb21wdXRlZCAmJiBub2RlLm9iamVjdC50eXBlICE9IFwiU3VwZXJcIiAmJiBub2RlLnByb3BlcnR5LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIpIHtcbiAgICBjb25zdCByZWNlaXZlciA9IGtub3duVmFsdWVFeHByZXNzaW9uVHlwZShub2RlLm9iamVjdCwgY29udGV4dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAocmVjZWl2ZXI/LmtpbmQgIT0gXCJSZWNvcmRUeXBlXCIpIHJldHVybiB1bmRlZmluZWRcbiAgICBjb25zdCBkZWNsYXJhdGlvbiA9IGNvbnRleHQucmVjb3Jkcy5nZXQocmVjZWl2ZXIuZGVjbGFyYXRpb25JZClcbiAgICBjb25zdCBtZW1iZXJOYW1lID0gbm9kZS5wcm9wZXJ0eS5uYW1lXG4gICAgY29uc3QgaW5kZXggPSBkZWNsYXJhdGlvbj8uZmllbGRzLmZpbmRJbmRleCgoZmllbGQpID0+IGZpZWxkLm5hbWUgPT0gbWVtYmVyTmFtZSkgPz8gLTFcblxuICAgIHJldHVybiBkZWNsYXJhdGlvbiA/IGluc3RhbnRpYXRlZFJlY29yZEZpZWxkVHlwZShkZWNsYXJhdGlvbiwgcmVjZWl2ZXIuYXJndW1lbnRzLCBpbmRleCkgOiB1bmRlZmluZWRcbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmIG5vZGUuY29tcHV0ZWQgJiYgbm9kZS5vYmplY3QudHlwZSAhPSBcIlN1cGVyXCIpIHtcbiAgICBjb25zdCBjb2xsZWN0aW9uVHlwZSA9IGtub3duVmFsdWVFeHByZXNzaW9uVHlwZShub2RlLm9iamVjdCwgY29udGV4dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAoY29sbGVjdGlvblR5cGU/LmtpbmQgPT0gXCJMaXN0VHlwZVwiKSByZXR1cm4gY29sbGVjdGlvblR5cGUuZWxlbWVudFR5cGVcbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiQ2FsbEV4cHJlc3Npb25cIiAmJiBub2RlLmNhbGxlZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmXG4gICAgIW5vZGUuY2FsbGVlLmNvbXB1dGVkICYmIG5vZGUuY2FsbGVlLm9iamVjdC50eXBlICE9IFwiU3VwZXJcIiAmJlxuICAgIG5vZGUuY2FsbGVlLnByb3BlcnR5LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiYgbm9kZS5jYWxsZWUucHJvcGVydHkubmFtZSA9PSBcImdldFwiKSB7XG4gICAgY29uc3QgY29sbGVjdGlvblR5cGUgPSBrbm93blZhbHVlRXhwcmVzc2lvblR5cGUobm9kZS5jYWxsZWUub2JqZWN0LCBjb250ZXh0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChjb2xsZWN0aW9uVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIiB8fCBjb2xsZWN0aW9uVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIpIHJldHVybiBjb2xsZWN0aW9uVHlwZS52YWx1ZVR5cGVcbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgdmFsdWUgdHlwZSBwcm9kdWNlZCBieSB0aGUgZnJvbnRlbmQncyBpbXBsaWNpdCBvcHRpb25hbC1iaW5kaW5nIHVud3JhcC5cbiAqIFNlbWFudGljIHZhbGlkYXRpb24gc2VwYXJhdGVseSBwcm92ZXMgdGhhdCB0aGUgdW53cmFwIG9jY3VycyBvbmx5IG9uIGEgcHJlc2VudCBwYXRoLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRXhwcmVzc2lvbn0gbm9kZSAtIFBhcnNlci1vd25lZCBleHByZXNzaW9uLlxuICogQHBhcmFtIHtKYXZhU2NyaXB0Q29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnRleHQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXJyb3JUeXBlIHwgdW5kZWZpbmVkfSBDb252ZXJ0ZWQgdmFsdWUgdHlwZS5cbiAqL1xuZnVuY3Rpb24ga25vd25WYWx1ZUV4cHJlc3Npb25UeXBlKG5vZGUsIGNvbnRleHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IHR5cGUgPSBrbm93bkV4cHJlc3Npb25UeXBlKG5vZGUsIGNvbnRleHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIHJldHVybiBub2RlLnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiYgdHlwZT8ua2luZCA9PSBcIk9wdGlvbmFsVHlwZVwiID8gdHlwZS52YWx1ZVR5cGUgOiB0eXBlXG59XG5cbi8qKlxuICogUmV0dXJucyBhIHN0YWJsZSBwYXJzZXItYm91bmRlZCBsb2NhdGlvbiBmb3Igb25lIGFic2VudCBhcnJheSBlbGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQXJyYXlFeHByZXNzaW9ufSBub2RlIC0gQXJyYXkgZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIE1pc3NpbmcgZWxlbWVudCBpbmRleC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IEhvbGUgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGFycmF5SG9sZUxvY2F0aW9uKG5vZGUsIGluZGV4LCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IHByZXZpb3VzID0gbm9kZS5lbGVtZW50cy5zbGljZSgwLCBpbmRleCkuZmluZExhc3QoKGVsZW1lbnQpID0+IGVsZW1lbnQgIT0gbnVsbClcbiAgY29uc3QgbmV4dCA9IG5vZGUuZWxlbWVudHMuc2xpY2UoaW5kZXggKyAxKS5maW5kKChlbGVtZW50KSA9PiBlbGVtZW50ICE9IG51bGwpXG4gIGNvbnN0IHN0YXJ0ID0gcHJldmlvdXM/LmVuZCA/PyAobm9kZS5zdGFydCA/PyAwKSArIDFcbiAgY29uc3QgZW5kID0gbmV4dD8uc3RhcnQgPz8gTWF0aC5tYXgoc3RhcnQgKyAxLCAobm9kZS5lbmQgPz8gc291cmNlLmxlbmd0aCkgLSAxKVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIHN0YXJ0LCBNYXRoLm1heChzdGFydCArIDEsIE1hdGgubWluKGVuZCwgc291cmNlLmxlbmd0aCkpKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIGEgc3VwcG9ydGVkIHJldHVybiBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdGF0ZW1lbnR9IG5vZGUgLSBCYWJlbCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtKYXZhU2NyaXB0Q29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZXR1cm5TdGF0ZW1lbnR9IFNlbWFudGljIHJldHVybi5cbiAqL1xuZnVuY3Rpb24gY29udmVydFJldHVybihub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnR5cGUgIT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBub2RlLnR5cGUsIGxvY2F0aW9uKVxuXG4gIHJldHVybiB7XG4gICAgLi4uKG5vZGUuYXJndW1lbnQgPyB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24oXG4gICAgICBub2RlLmFyZ3VtZW50LFxuICAgICAgbGFuZ3VhZ2UsXG4gICAgICBmaWxlbmFtZSxcbiAgICAgIHNvdXJjZSxcbiAgICAgIGNvbnRleHQsXG4gICAgICBjb250ZXh0LnJldHVyblR5cGU/LmtpbmQgPT0gXCJUeXBlUmVmZXJlbmNlXCIgJiYgY29udGV4dC5yZXR1cm5UeXBlLm5hbWUgPT0gXCJ2b2lkXCIgPyB1bmRlZmluZWQgOiBjb250ZXh0LnJldHVyblR5cGVcbiAgICApfSA6IHt9KSxcbiAgICBraW5kOiBcIlJldHVyblN0YXRlbWVudFwiLFxuICAgIGxvY2F0aW9uXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgc3VwcG9ydGVkIGxvY2FsIGRlY2xhcmF0aW9uIG9yIGFzc2lnbm1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdGF0ZW1lbnR9IG5vZGUgLSBCYWJlbCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtKYXZhU2NyaXB0Q29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Mb2NhbFN0YXRlbWVudCB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50fSBTZW1hbnRpYyBsb2NhbCBvciBwcml2YXRlLWZpZWxkIHN0YXRlbWVudC5cbiAqL1xuZnVuY3Rpb24gY29udmVydExvY2FsU3RhdGVtZW50KG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUudHlwZSA9PSBcIlZhcmlhYmxlRGVjbGFyYXRpb25cIikge1xuICAgIGlmICghW1wibGV0XCIsIFwiY29uc3RcIl0uaW5jbHVkZXMobm9kZS5raW5kKSB8fCBub2RlLmRlY2xhcmF0aW9ucy5sZW5ndGggIT0gMSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBgJHtub2RlLmtpbmR9IGRlY2xhcmF0aW9uYCwgbG9jYXRpb24pXG4gICAgfVxuXG4gICAgY29uc3QgZGVjbGFyYXRvciA9IG5vZGUuZGVjbGFyYXRpb25zWzBdXG4gICAgY29uc3QgZGVjbGFyYXRvckxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKGRlY2xhcmF0b3IsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAoZGVjbGFyYXRvci5pZC50eXBlICE9IFwiSWRlbnRpZmllclwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGRlY2xhcmF0b3IuaWQudHlwZSwgZGVjbGFyYXRvckxvY2F0aW9uKVxuICAgIGlmICghZGVjbGFyYXRvci5pbml0KSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwidW5pbml0aWFsaXplZCBkZWNsYXJhdGlvblwiLCBkZWNsYXJhdG9yTG9jYXRpb24pXG5cbiAgICBsZXQgdHlwZSA9IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiXG4gICAgICA/IGNvbnZlcnRUeXBlU2NyaXB0VHlwZShkZWNsYXJhdG9yLmlkLnR5cGVBbm5vdGF0aW9uLCBgTG9jYWwgJyR7ZGVjbGFyYXRvci5pZC5uYW1lfSdgLCBkZWNsYXJhdG9yTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsXG4gICAgICAgIGNvbnRleHQucmVjb3JkTmFtZXMsIGNvbnRleHQudHlwZVBhcmFtZXRlcnMpXG4gICAgICA6IGxvY2FsSmF2YVNjcmlwdFR5cGUobm9kZSwgZGVjbGFyYXRvci5pZC5uYW1lLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LnJlY29yZE5hbWVzLCBjb250ZXh0LnR5cGVQYXJhbWV0ZXJzKVxuXG4gICAgaWYgKG5vZGUua2luZCA9PSBcImNvbnN0XCIgJiYgdHlwZS5raW5kID09IFwiTWFwVHlwZVwiICYmIGNvbnRleHQub3JkZXJlZE1hcERlY2xhcmF0aW9ucz8uaGFzKGRlY2xhcmF0b3IpICYmXG4gICAgICBkZWNsYXJhdG9yLmluaXQudHlwZSA9PSBcIk5ld0V4cHJlc3Npb25cIiAmJiBkZWNsYXJhdG9yLmluaXQuY2FsbGVlLnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiZcbiAgICAgIGRlY2xhcmF0b3IuaW5pdC5jYWxsZWUubmFtZSA9PSBcIk1hcFwiICYmIG5hdGl2ZU1hcEF2YWlsYWJsZShjb250ZXh0KSkge1xuICAgICAgdHlwZSA9IG9yZGVyZWRNYXBUeXBlRnJvbU1hcCh0eXBlLCBkZWNsYXJhdG9yTG9jYXRpb24pXG4gICAgfVxuXG4gICAgY29uc3Qgc2VtYW50aWMgPSB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGluaXRpYWxpemVyOiBjb252ZXJ0RXhwcmVzc2lvbihkZWNsYXJhdG9yLmluaXQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0LCB0eXBlKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkxvY2FsRGVjbGFyYXRpb25cIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIG11dGFibGU6IG5vZGUua2luZCA9PSBcImxldFwiLFxuICAgICAgbmFtZTogZGVjbGFyYXRvci5pZC5uYW1lLFxuICAgICAgdHlwZVxuICAgIH0sIHtcbiAgICAgIG5hbWU6IGlkZW50aWZpZXJMb2NhdGlvbihkZWNsYXJhdG9yLmlkLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKGRlY2xhcmF0b3IsIFwiPVwiLCBkZWNsYXJhdG9yLmlkLmVuZCA/PyBkZWNsYXJhdG9yLnN0YXJ0ID8/IDAsIGRlY2xhcmF0b3IuaW5pdC5zdGFydCA/PyBkZWNsYXJhdG9yLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIH0pXG5cbiAgICBjb250ZXh0LmJpbmRpbmdzLnNldChkZWNsYXJhdG9yLmlkLm5hbWUsIHR5cGUpXG4gICAgcmV0dXJuIHNlbWFudGljXG4gIH1cblxuICBpZiAobm9kZS50eXBlID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiICYmIG5vZGUuZXhwcmVzc2lvbi50eXBlID09IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGFzc2lnbm1lbnQgPSBub2RlLmV4cHJlc3Npb25cbiAgICBjb25zdCB0YXJnZXRMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihhc3NpZ25tZW50LmxlZnQsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAoYXNzaWdubWVudC5vcGVyYXRvciAhPSBcIj1cIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBgYXNzaWdubWVudCAke2Fzc2lnbm1lbnQub3BlcmF0b3J9YCwgbG9jYXRpb24pXG4gICAgaWYgKGFzc2lnbm1lbnQubGVmdC50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmICFhc3NpZ25tZW50LmxlZnQuY29tcHV0ZWQgJiZcbiAgICAgIGFzc2lnbm1lbnQubGVmdC5vYmplY3QudHlwZSA9PSBcIlRoaXNFeHByZXNzaW9uXCIgJiYgY29udGV4dC5jdXJyZW50Q2xhc3MpIHtcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLklkZW50aWZpZXIgfCB1bmRlZmluZWR9ICovXG4gICAgICBsZXQgcHJvcGVydHlcblxuICAgICAgaWYgKGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiICYmIGFzc2lnbm1lbnQubGVmdC5wcm9wZXJ0eS50eXBlID09IFwiUHJpdmF0ZU5hbWVcIikgcHJvcGVydHkgPSBhc3NpZ25tZW50LmxlZnQucHJvcGVydHkuaWRcbiAgICAgIGlmIChsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiAmJiBhc3NpZ25tZW50LmxlZnQucHJvcGVydHkudHlwZSA9PSBcIklkZW50aWZpZXJcIikgcHJvcGVydHkgPSBhc3NpZ25tZW50LmxlZnQucHJvcGVydHlcbiAgICAgIGlmICghcHJvcGVydHkpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJub25jYW5vbmljYWwgcHJpdmF0ZSBpbnN0YW5jZSBmaWVsZCBhc3NpZ25tZW50XCIsIGxvY2F0aW9uKVxuICAgICAgY29uc3QgZmllbGQgPSBjb250ZXh0LmN1cnJlbnRDbGFzcy5maWVsZHMuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUubmFtZSA9PSBwcm9wZXJ0eS5uYW1lKVxuXG4gICAgICBpZiAoIWZpZWxkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGB1bmtub3duIHByaXZhdGUgZmllbGQgJyR7cHJvcGVydHkubmFtZX0nYCwgaWRlbnRpZmllckxvY2F0aW9uKHByb3BlcnR5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgICAgZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIGZpZWxkLnR5cGUpLFxuICAgICAgICBmaWVsZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChmaWVsZC5pZCksXG4gICAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlByaXZhdGVGaWVsZFdyaXRlU3RhdGVtZW50XCIpLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgcmVjZWl2ZXI6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjZWl2ZXJFeHByZXNzaW9ufSAqLyAoXG4gICAgICAgICAgY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5sZWZ0Lm9iamVjdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpKVxuICAgICAgfSwge21lbWJlcjogaWRlbnRpZmllckxvY2F0aW9uKHByb3BlcnR5LCBmaWxlbmFtZSwgc291cmNlKSwgb3BlcmF0b3I6IHRva2VuTG9jYXRpb24oYXNzaWdubWVudCwgXCI9XCIsXG4gICAgICAgIGFzc2lnbm1lbnQubGVmdC5lbmQgPz8gYXNzaWdubWVudC5zdGFydCA/PyAwLCBhc3NpZ25tZW50LnJpZ2h0LnN0YXJ0ID8/IGFzc2lnbm1lbnQuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgICB9XG4gICAgaWYgKGFzc2lnbm1lbnQubGVmdC50eXBlICE9IFwiSWRlbnRpZmllclwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGFzc2lnbm1lbnQubGVmdC50eXBlLCB0YXJnZXRMb2NhdGlvbilcblxuICAgIGNvbnN0IHRhcmdldCA9IHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbjogdGFyZ2V0TG9jYXRpb24sIG5hbWU6IGFzc2lnbm1lbnQubGVmdC5uYW1lfSwge1xuICAgICAgbmFtZTogaWRlbnRpZmllckxvY2F0aW9uKGFzc2lnbm1lbnQubGVmdCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuXG4gICAgY29uc3QgYmluZGluZ1R5cGUgPSBjb250ZXh0LmJpbmRpbmdzLmdldChhc3NpZ25tZW50LmxlZnQubmFtZSlcbiAgICBjb25zdCBzZW1hbnRpYyA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24oYXNzaWdubWVudC5yaWdodCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsXG4gICAgICAgIGJpbmRpbmdUeXBlPy5raW5kID09IFwiRXJyb3JUeXBlXCIgPyB1bmRlZmluZWQgOiBiaW5kaW5nVHlwZSksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJBc3NpZ25tZW50U3RhdGVtZW50XCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICB0YXJnZXRcbiAgICB9LCB7XG4gICAgICBvcGVyYXRvcjogdG9rZW5Mb2NhdGlvbihhc3NpZ25tZW50LCBcIj1cIiwgYXNzaWdubWVudC5sZWZ0LmVuZCA/PyBhc3NpZ25tZW50LnN0YXJ0ID8/IDAsIGFzc2lnbm1lbnQucmlnaHQuc3RhcnQgPz8gYXNzaWdubWVudC5lbmQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuXG4gICAgcmV0dXJuIHNlbWFudGljXG4gIH1cblxuICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIG5vZGUudHlwZSwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogUmVhZHMgYW4gaW1tZWRpYXRlbHkgYXNzb2NpYXRlZCBKYXZhU2NyaXB0IGxvY2FsIGBAdHlwZWAgdGFnLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuVmFyaWFibGVEZWNsYXJhdGlvbn0gbm9kZSAtIExvY2FsIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBMb2NhbCBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXI+fSBbdHlwZVBhcmFtZXRlcnNdIC0gRGVjbGFyYXRpb24tc2NvcGVkIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IFNlbWFudGljIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGxvY2FsSmF2YVNjcmlwdFR5cGUobm9kZSwgbmFtZSwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJzID0gbmV3IE1hcCgpKSB7XG4gIGNvbnN0IGNvbW1lbnQgPSBub2RlLmxlYWRpbmdDb21tZW50cz8uYXQoLTEpXG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKCFjb21tZW50IHx8IGNvbW1lbnQudHlwZSAhPSBcIkNvbW1lbnRCbG9ja1wiIHx8ICFjb21tZW50LnZhbHVlLnN0YXJ0c1dpdGgoXCIqXCIpKSB7XG4gICAgcmV0dXJuIG1pc3NpbmdUeXBlKFwiamF2YXNjcmlwdFwiLCBgTG9jYWwgJyR7bmFtZX0nYCwgbG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBnYXAgPSBzb3VyY2Uuc2xpY2UoY29tbWVudC5lbmQgPz8gMCwgbm9kZS5zdGFydCA/PyAwKVxuXG4gIGlmICghL15cXHMqJC91LnRlc3QoZ2FwKSB8fCAoZ2FwLm1hdGNoKC9cXG4vZ3UpPy5sZW5ndGggPz8gMCkgPiAxKSB7XG4gICAgcmV0dXJuIG1pc3NpbmdUeXBlKFwiamF2YXNjcmlwdFwiLCBgTG9jYWwgJyR7bmFtZX0nYCwgbG9jYXRpb24pXG4gIH1cblxuICBjb25zdCBibG9jayA9IHBhcnNlQ29tbWVudChgLyoke2NvbW1lbnQudmFsdWV9Ki9gKVswXVxuICBjb25zdCB0YWdzID0gYmxvY2s/LnRhZ3MuZmlsdGVyKCh0YWcpID0+IHRhZy50YWcgPT0gXCJ0eXBlXCIpID8/IFtdXG5cbiAgY29uc3QgdGFnID0gdGFncy5sZW5ndGggPT0gMSA/IHRhZ3NbMF0gOiB1bmRlZmluZWRcblxuICByZXR1cm4gY29udmVydFR5cGUoXG4gICAgdGFnPy50eXBlLFxuICAgIFwiamF2YXNjcmlwdFwiLFxuICAgIGBMb2NhbCAnJHtuYW1lfSdgLFxuICAgIGxvY2F0aW9uLFxuICAgIHNvdXJjZSxcbiAgICB0YWcgPyBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudCwgdGFnLCBcInR5cGVcIiwgZmlsZW5hbWUsIHNvdXJjZSkgOiBsb2NhdGlvbixcbiAgICByZWNvcmROYW1lcyxcbiAgICB0eXBlUGFyYW1ldGVyc1xuICApXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGV4aGF1c3RpdmUgQmFiZWwgc3RhdGVtZW50LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuU3RhdGVtZW50fSBub2RlIC0gQmFiZWwgc3RhdGVtZW50LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBnZW5lcmF0ZWQgc2NhbGFyIG91dHB1dCBtYXkgY29udGFpbiBzaWduZWQgemVyby5cbiAqIEBwYXJhbSB7SmF2YVNjcmlwdENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgbGV4aWNhbCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRTdGF0ZW1lbnQobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dCkge1xuICBpZiAobm9kZS50eXBlID09IFwiUmV0dXJuU3RhdGVtZW50XCIpIHJldHVybiBjb252ZXJ0UmV0dXJuKG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICBpZiAobm9kZS50eXBlID09IFwiSWZTdGF0ZW1lbnRcIikgcmV0dXJuIGNvbnZlcnRJZihub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjb250ZXh0KVxuICBpZiAobm9kZS50eXBlID09IFwiVGhyb3dTdGF0ZW1lbnRcIikgcmV0dXJuIGNvbnZlcnRUeXBlZFRocm93KG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICBpZiAobm9kZS50eXBlID09IFwiVHJ5U3RhdGVtZW50XCIpIHJldHVybiBjb252ZXJ0VHlwZWRUcnkobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dClcbiAgaWYgKG5vZGUudHlwZSA9PSBcIldoaWxlU3RhdGVtZW50XCIpIHJldHVybiBjb252ZXJ0V2hpbGUobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dClcbiAgaWYgKG5vZGUudHlwZSA9PSBcIkZvck9mU3RhdGVtZW50XCIpIHJldHVybiBjb252ZXJ0Rm9yRWFjaChub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjb250ZXh0KVxuICBpZiAobm9kZS50eXBlID09IFwiQnJlYWtTdGF0ZW1lbnRcIiB8fCBub2RlLnR5cGUgPT0gXCJDb250aW51ZVN0YXRlbWVudFwiKSB7XG4gICAgaWYgKG5vZGUubGFiZWwpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgYGxhYmVsZWQgJHtub2RlLnR5cGUgPT0gXCJCcmVha1N0YXRlbWVudFwiID8gXCJicmVha1wiIDogXCJjb250aW51ZVwifWAsXG4gICAgICBub2RlTG9jYXRpb24obm9kZS5sYWJlbCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgY29uc3Qga2V5d29yZCA9IG5vZGUudHlwZSA9PSBcIkJyZWFrU3RhdGVtZW50XCIgPyBcImJyZWFrXCIgOiBcImNvbnRpbnVlXCJcbiAgICBjb25zdCBsb2NhdGlvbiA9IHRva2VuTG9jYXRpb24obm9kZSwga2V5d29yZCwgbm9kZS5zdGFydCA/PyAwLCBub2RlLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IG5vZGUudHlwZSwgbG9jYXRpb259LCB7a2V5d29yZDogbG9jYXRpb259KVxuICB9XG4gIGlmIChub2RlLnR5cGUgPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIgfHwgbm9kZS50eXBlID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiICYmIG5vZGUuZXhwcmVzc2lvbi50eXBlID09IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIikge1xuICAgIHJldHVybiBjb252ZXJ0TG9jYWxTdGF0ZW1lbnQobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpXG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIikge1xuICAgIGlmIChub2RlLmV4cHJlc3Npb24udHlwZSA9PSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgKG5vZGUuZXhwcmVzc2lvbi5jYWxsZWUudHlwZSA9PSBcIklkZW50aWZpZXJcIiB8fFxuICAgICAgbm9kZS5leHByZXNzaW9uLmNhbGxlZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmICFub2RlLmV4cHJlc3Npb24uY2FsbGVlLmNvbXB1dGVkICYmXG4gICAgICBub2RlLmV4cHJlc3Npb24uY2FsbGVlLm9iamVjdC50eXBlICE9IFwiU3VwZXJcIiAmJlxuICAgICAgW1wiUmVmZXJlbmNlVHlwZVwiLCBcIk93bmVkUmVmZXJlbmNlVHlwZVwiXS5pbmNsdWRlcyhTdHJpbmcoXG4gICAgICAgIGtub3duVmFsdWVFeHByZXNzaW9uVHlwZShub2RlLmV4cHJlc3Npb24uY2FsbGVlLm9iamVjdCwgY29udGV4dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpPy5raW5kKSkpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBleHByZXNzaW9uOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNhbGxFeHByZXNzaW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuTWV0aG9kQ2FsbEV4cHJlc3Npb259ICovIChcbiAgICAgICAgICBjb252ZXJ0RXhwcmVzc2lvbihub2RlLmV4cHJlc3Npb24sIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KVxuICAgICAgICApLFxuICAgICAgICBraW5kOiBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIixcbiAgICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb252ZXJ0UHJpbnQobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dClcbiAgfVxuXG4gIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG59XG5cbi8qKlxuICogQ29udmVydHMgZXhhY3QgYHRocm93IG5ldyBEZWNsYXJlZEVycm9yKG1lc3NhZ2UpYC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlRocm93U3RhdGVtZW50fSBub2RlIC0gQmFiZWwgdGhyb3cgc3RhdGVtZW50LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7SmF2YVNjcmlwdENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgbGV4aWNhbCBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJhaXNlU3RhdGVtZW50fSBTZW1hbnRpYyByYWlzZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFR5cGVkVGhyb3cobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgYXJndW1lbnQgPSBub2RlLmFyZ3VtZW50XG5cbiAgaWYgKCFhcmd1bWVudCB8fCBhcmd1bWVudC50eXBlICE9IFwiTmV3RXhwcmVzc2lvblwiIHx8IGFyZ3VtZW50LmNhbGxlZS50eXBlICE9IFwiSWRlbnRpZmllclwiIHx8XG4gICAgY29udGV4dC5iaW5kaW5ncy5oYXMoYXJndW1lbnQuY2FsbGVlLm5hbWUpIHx8ICFjb250ZXh0LmVycm9yTmFtZXMuaGFzKGFyZ3VtZW50LmNhbGxlZS5uYW1lKSB8fCBhcmd1bWVudC5hcmd1bWVudHMubGVuZ3RoICE9IDEgfHxcbiAgICBhcmd1bWVudC5hcmd1bWVudHNbMF0udHlwZSA9PSBcIlNwcmVhZEVsZW1lbnRcIiB8fCBhcmd1bWVudC5hcmd1bWVudHNbMF0udHlwZSA9PSBcIkFyZ3VtZW50UGxhY2Vob2xkZXJcIiB8fFxuICAgIGFyZ3VtZW50LnR5cGVBcmd1bWVudHMgfHwgYXJndW1lbnQudHlwZVBhcmFtZXRlcnMpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwidGhyb3cgb3RoZXIgdGhhbiBleGFjdCBkZWNsYXJlZCBlcnJvciBjb25zdHJ1Y3Rpb25cIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgZGVjbGFyYXRpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb259ICovIChjb250ZXh0LmVycm9yTmFtZXMuZ2V0KGFyZ3VtZW50LmNhbGxlZS5uYW1lKSlcbiAgY29uc3QgdHlwZUxvY2F0aW9uID0gaWRlbnRpZmllckxvY2F0aW9uKGFyZ3VtZW50LmNhbGxlZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgZXJyb3I6IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAgZXJyb3I6IHdpdGhQYXJzZXJSYW5nZXMoe2RlY2xhcmF0aW9uSWQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFcnJvclR5cGVcIil9LCB7dHlwZTogdHlwZUxvY2F0aW9ufSksXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFcnJvckNvbnN0cnVjdGlvblwiKSxcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24oYXJndW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgbWVzc2FnZTogY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQuYXJndW1lbnRzWzBdLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgICB9LCB7dHlwZTogdHlwZUxvY2F0aW9ufSksXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmFpc2VTdGF0ZW1lbnRcIiksXG4gICAgbG9jYXRpb25cbiAgfSwge2tleXdvcmQ6IHRva2VuTG9jYXRpb24obm9kZSwgXCJ0aHJvd1wiLCBub2RlLnN0YXJ0ID8/IDAsIGFyZ3VtZW50LnN0YXJ0ID8/IG5vZGUuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgY2F0Y2ggd2l0aCB0aGUgY2Fub25pY2FsIGBpbnN0YW5jZW9mYCBndWFyZCBhbmQgZXhhY3QgcmV0aHJvdy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlRyeVN0YXRlbWVudH0gbm9kZSAtIEJhYmVsIHRyeSBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtib29sZWFufSBjYW5vbmljYWxaZXJvUmVxdWlyZWQgLSBXaGV0aGVyIHNjYWxhciBvdXRwdXQgY2Fub25pY2FsaXplcyB6ZXJvLlxuICogQHBhcmFtIHtKYXZhU2NyaXB0Q29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHJ5U3RhdGVtZW50fSBTZW1hbnRpYyBleGFjdCBoYW5kbGVyLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0VHlwZWRUcnkobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLmZpbmFsaXplciB8fCAhbm9kZS5oYW5kbGVyIHx8IG5vZGUuaGFuZGxlci5wYXJhbT8udHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fCBub2RlLmhhbmRsZXIuYm9keS5kaXJlY3RpdmVzLmxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwidHJ5IHdpdGhvdXQgb25lIGV4cGxpY2l0IGd1YXJkZWQgY2F0Y2hcIiwgbG9jYXRpb24pXG4gIH1cbiAgY29uc3QgYmluZGluZyA9IG5vZGUuaGFuZGxlci5wYXJhbVxuICBjb25zdCBndWFyZCA9IG5vZGUuaGFuZGxlci5ib2R5LmJvZHlbMF1cblxuICBpZiAoIWd1YXJkIHx8IGd1YXJkLnR5cGUgIT0gXCJJZlN0YXRlbWVudFwiIHx8IGd1YXJkLmFsdGVybmF0ZSB8fCBndWFyZC50ZXN0LnR5cGUgIT0gXCJVbmFyeUV4cHJlc3Npb25cIiB8fFxuICAgIGd1YXJkLnRlc3Qub3BlcmF0b3IgIT0gXCIhXCIgfHwgZ3VhcmQudGVzdC5hcmd1bWVudC50eXBlICE9IFwiQmluYXJ5RXhwcmVzc2lvblwiIHx8IGd1YXJkLnRlc3QuYXJndW1lbnQub3BlcmF0b3IgIT0gXCJpbnN0YW5jZW9mXCIgfHxcbiAgICBndWFyZC50ZXN0LmFyZ3VtZW50LmxlZnQudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fCBndWFyZC50ZXN0LmFyZ3VtZW50LmxlZnQubmFtZSAhPSBiaW5kaW5nLm5hbWUgfHxcbiAgICBndWFyZC50ZXN0LmFyZ3VtZW50LnJpZ2h0LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgZ3VhcmQudGVzdC5hcmd1bWVudC5yaWdodC5uYW1lID09IGJpbmRpbmcubmFtZSB8fFxuICAgIGNvbnRleHQuYmluZGluZ3MuaGFzKGd1YXJkLnRlc3QuYXJndW1lbnQucmlnaHQubmFtZSkgfHwgIWNvbnRleHQuZXJyb3JOYW1lcy5oYXMoZ3VhcmQudGVzdC5hcmd1bWVudC5yaWdodC5uYW1lKSB8fFxuICAgIGd1YXJkLmNvbnNlcXVlbnQudHlwZSAhPSBcIkJsb2NrU3RhdGVtZW50XCIgfHwgZ3VhcmQuY29uc2VxdWVudC5ib2R5Lmxlbmd0aCAhPSAxIHx8IGd1YXJkLmNvbnNlcXVlbnQuZGlyZWN0aXZlcy5sZW5ndGggPiAwIHx8XG4gICAgZ3VhcmQuY29uc2VxdWVudC5ib2R5WzBdLnR5cGUgIT0gXCJUaHJvd1N0YXRlbWVudFwiIHx8IGd1YXJkLmNvbnNlcXVlbnQuYm9keVswXS5hcmd1bWVudD8udHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fFxuICAgIGd1YXJkLmNvbnNlcXVlbnQuYm9keVswXS5hcmd1bWVudC5uYW1lICE9IGJpbmRpbmcubmFtZSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJjYXRjaCB3aXRob3V0IGV4YWN0IGluc3RhbmNlb2YgZ3VhcmQgYW5kIHVubWF0Y2hlZCByZXRocm93XCIsIG5vZGVMb2NhdGlvbihndWFyZCA/PyBub2RlLmhhbmRsZXIsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSAqLyAoY29udGV4dC5lcnJvck5hbWVzLmdldChndWFyZC50ZXN0LmFyZ3VtZW50LnJpZ2h0Lm5hbWUpKVxuICBjb25zdCBjYXVnaHRUeXBlTG9jYXRpb24gPSBpZGVudGlmaWVyTG9jYXRpb24oZ3VhcmQudGVzdC5hcmd1bWVudC5yaWdodCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY2F0Y2hUeXBlID0gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgZGVjbGFyYXRpb25JZDogLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiRXJyb3JUeXBlXCIpXG4gIH0sIHt0eXBlOiBjYXVnaHRUeXBlTG9jYXRpb259KVxuICBjb25zdCBib2R5Q29udGV4dCA9IHsuLi5jb250ZXh0LCBiaW5kaW5nczogbmV3IE1hcChjb250ZXh0LmJpbmRpbmdzKX1cbiAgY29uc3QgY2F0Y2hDb250ZXh0ID0gey4uLmNvbnRleHQsIGJpbmRpbmdzOiBuZXcgTWFwKGNvbnRleHQuYmluZGluZ3MpfVxuXG4gIGNhdGNoQ29udGV4dC5iaW5kaW5ncy5zZXQoYmluZGluZy5uYW1lLCBjYXRjaFR5cGUpXG4gIGNvbnN0IGNhdGNoU3RhdGVtZW50cyA9IG5vZGUuaGFuZGxlci5ib2R5LmJvZHkuc2xpY2UoMSlcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keTogY29udmVydEJsb2NrKG5vZGUuYmxvY2ssIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGJvZHlDb250ZXh0KSxcbiAgICBjYXRjaEJpbmRpbmc6IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQ2F0Y2hCaW5kaW5nXCIpLFxuICAgICAgbG9jYXRpb246IGlkZW50aWZpZXJMb2NhdGlvbihiaW5kaW5nLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIG11dGFibGU6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSksXG4gICAgICBuYW1lOiBiaW5kaW5nLm5hbWUsXG4gICAgICB0eXBlOiBjYXRjaFR5cGVcbiAgICB9LCB7bmFtZTogaWRlbnRpZmllckxvY2F0aW9uKGJpbmRpbmcsIGZpbGVuYW1lLCBzb3VyY2UpfSksXG4gICAgY2F0Y2hCb2R5OiBjb252ZXJ0QmxvY2soY2F0Y2hTdGF0ZW1lbnRzLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjYXRjaENvbnRleHQsXG4gICAgICBub2RlTG9jYXRpb24obm9kZS5oYW5kbGVyLmJvZHksIGZpbGVuYW1lLCBzb3VyY2UpKSxcbiAgICBjYXRjaFR5cGUsXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHJ5U3RhdGVtZW50XCIpLFxuICAgIGxvY2F0aW9uXG4gIH0sIHtcbiAgICBjYXRjaDogdG9rZW5Mb2NhdGlvbihub2RlLmhhbmRsZXIsIFwiY2F0Y2hcIiwgbm9kZS5oYW5kbGVyLnN0YXJ0ID8/IDAsIGJpbmRpbmcuc3RhcnQgPz8gbm9kZS5oYW5kbGVyLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBndWFyZDogbm9kZUxvY2F0aW9uKGd1YXJkLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICB0cnk6IHRva2VuTG9jYXRpb24obm9kZSwgXCJ0cnlcIiwgbm9kZS5zdGFydCA/PyAwLCBub2RlLmJsb2NrLnN0YXJ0ID8/IG5vZGUuZW5kID8/IHNvdXJjZS5sZW5ndGgsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0pXG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGV4YWN0IGJsb2NrLWJvZGllZCBgZm9yIChjb25zdCB2YWx1ZSBvZiBsaXN0KWAgcHJvZmlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkZvck9mU3RhdGVtZW50fSBub2RlIC0gQmFiZWwgZm9yLW9mIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNhbm9uaWNhbFplcm9SZXF1aXJlZCAtIFdoZXRoZXIgc2NhbGFyIG91dHB1dCBjYW5vbmljYWxpemVzIHplcm8uXG4gKiBAcGFyYW0ge0phdmFTY3JpcHRDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGxleGljYWwgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkZvckVhY2hTdGF0ZW1lbnQgfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Gb3JFYWNoTWFwU3RhdGVtZW50fSBTZW1hbnRpYyBsb29wLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0Rm9yRWFjaChub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjb250ZXh0KSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUuYXdhaXQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJhc3luYyBmb3Itb2ZcIiwgbG9jYXRpb24pXG4gIGlmIChub2RlLmxlZnQudHlwZSAhPSBcIlZhcmlhYmxlRGVjbGFyYXRpb25cIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImZvci1vZiBhc3NpZ25tZW50IGJpbmRpbmdcIiwgbm9kZUxvY2F0aW9uKG5vZGUubGVmdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGlmIChub2RlLmxlZnQua2luZCAhPSBcImNvbnN0XCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGAke25vZGUubGVmdC5raW5kfSBpdGVyYXRpb24gYmluZGluZ2AsIHRva2VuTG9jYXRpb24oXG4gICAgICBub2RlLmxlZnQsXG4gICAgICBub2RlLmxlZnQua2luZCxcbiAgICAgIG5vZGUubGVmdC5zdGFydCA/PyBub2RlLnN0YXJ0ID8/IDAsXG4gICAgICBub2RlLmxlZnQuZW5kID8/IG5vZGUuZW5kID8/IHNvdXJjZS5sZW5ndGgsXG4gICAgICBmaWxlbmFtZSxcbiAgICAgIHNvdXJjZVxuICAgICkpXG4gIH1cbiAgaWYgKG5vZGUubGVmdC5kZWNsYXJhdGlvbnMubGVuZ3RoICE9IDEpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJtdWx0aXBsZSBpdGVyYXRpb24gYmluZGluZ3NcIiwgbm9kZUxvY2F0aW9uKG5vZGUubGVmdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGNvbnN0IGRlY2xhcmF0b3IgPSBub2RlLmxlZnQuZGVjbGFyYXRpb25zWzBdXG5cbiAgaWYgKGRlY2xhcmF0b3IuaWQudHlwZSA9PSBcIkFycmF5UGF0dGVyblwiKSB7XG4gICAgY29uc3QgW2tleSwgdmFsdWVdID0gZGVjbGFyYXRvci5pZC5lbGVtZW50c1xuXG4gICAgaWYgKGRlY2xhcmF0b3IuaWQuZWxlbWVudHMubGVuZ3RoICE9IDIgfHwgIWtleSB8fCAhdmFsdWUgfHwga2V5LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgdmFsdWUudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fFxuICAgICAgZGVjbGFyYXRvci5pZC50eXBlQW5ub3RhdGlvbiB8fCBrZXkudHlwZUFubm90YXRpb24gfHwgdmFsdWUudHlwZUFubm90YXRpb24gfHwga2V5Lm9wdGlvbmFsIHx8IHZhbHVlLm9wdGlvbmFsKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibWFwIGl0ZXJhdGlvbiBiaW5kaW5nIHNoYXBlXCIsIG5vZGVMb2NhdGlvbihkZWNsYXJhdG9yLmlkLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgaWYgKGRlY2xhcmF0b3IuaW5pdCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImluaXRpYWxpemVkIGl0ZXJhdGlvbiBiaW5kaW5nXCIsIG5vZGVMb2NhdGlvbihkZWNsYXJhdG9yLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICBpZiAobm9kZS5ib2R5LnR5cGUgIT0gXCJCbG9ja1N0YXRlbWVudFwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiZm9yLW9mIHdpdGhvdXQgYmxvY2sgYm9keVwiLCBub2RlTG9jYXRpb24obm9kZS5ib2R5LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICBjb25zdCBjb2xsZWN0aW9uVHlwZSA9IGl0ZXJhdGlvbk9wZXJhbmRUeXBlKGtub3duRXhwcmVzc2lvblR5cGUobm9kZS5yaWdodCwgY29udGV4dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gICAgaWYgKGNvbGxlY3Rpb25UeXBlPy5raW5kID09IFwiTWFwVHlwZVwiKSB7XG4gICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwidW5vcmRlcmVkIG1hcCBpdGVyYXRpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBpZiAoIWNvbGxlY3Rpb25UeXBlIHx8IGNvbGxlY3Rpb25UeXBlLmtpbmQgIT0gXCJPcmRlcmVkTWFwVHlwZVwiKSB7XG4gICAgICByZXR1cm4gbWlzc2luZ1R5cGUobGFuZ3VhZ2UsIFwiT3JkZXJlZCBtYXAgaXRlcmF0aW9uIGNvbGxlY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBjb25zdCBrZXlMb2NhdGlvbiA9IGlkZW50aWZpZXJMb2NhdGlvbihrZXksIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgdmFsdWVMb2NhdGlvbiA9IGlkZW50aWZpZXJMb2NhdGlvbih2YWx1ZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBrZXlUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoY29sbGVjdGlvblR5cGUua2V5VHlwZSwga2V5TG9jYXRpb24pXG4gICAgY29uc3QgdmFsdWVUeXBlID0gaXRlcmF0aW9uQmluZGluZ1R5cGUoY29sbGVjdGlvblR5cGUudmFsdWVUeXBlLCB2YWx1ZUxvY2F0aW9uKVxuICAgIGNvbnN0IGtleUJpbmRpbmcgPSB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlZhbHVlQmluZGluZ1wiKSwgbG9jYXRpb246IGtleUxvY2F0aW9uLCBtdXRhYmxlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpLFxuICAgICAgbmFtZToga2V5Lm5hbWUsIHR5cGU6IGtleVR5cGVcbiAgICB9LCB7bmFtZToga2V5TG9jYXRpb259KVxuICAgIGNvbnN0IHZhbHVlQmluZGluZyA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVmFsdWVCaW5kaW5nXCIpLCBsb2NhdGlvbjogdmFsdWVMb2NhdGlvbiwgbXV0YWJsZTogLyoqIEB0eXBlIHtjb25zdH0gKi8gKGZhbHNlKSxcbiAgICAgIG5hbWU6IHZhbHVlLm5hbWUsIHR5cGU6IHZhbHVlVHlwZVxuICAgIH0sIHtuYW1lOiB2YWx1ZUxvY2F0aW9ufSlcbiAgICBjb25zdCBib2R5Q29udGV4dCA9IHsuLi5jb250ZXh0LCBiaW5kaW5nczogbmV3IE1hcChjb250ZXh0LmJpbmRpbmdzKX1cblxuICAgIGJvZHlDb250ZXh0LmJpbmRpbmdzLnNldChrZXkubmFtZSwga2V5VHlwZSlcbiAgICBib2R5Q29udGV4dC5iaW5kaW5ncy5zZXQodmFsdWUubmFtZSwgdmFsdWVUeXBlKVxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGJvZHk6IGNvbnZlcnRCbG9jayhub2RlLmJvZHksIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGJvZHlDb250ZXh0KSxcbiAgICAgIGtleUJpbmRpbmcsXG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJGb3JFYWNoTWFwU3RhdGVtZW50XCIpLFxuICAgICAgbG9jYXRpb24sXG4gICAgICBtYXA6IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUucmlnaHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICAgIHZhbHVlQmluZGluZ1xuICAgIH0sIHtcbiAgICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKG5vZGUsIFwib2ZcIiwgbm9kZS5sZWZ0LmVuZCA/PyBub2RlLnN0YXJ0ID8/IDAsIG5vZGUucmlnaHQuc3RhcnQgPz8gbm9kZS5lbmQgPz8gc291cmNlLmxlbmd0aCxcbiAgICAgICAgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuICB9XG4gIGlmIChkZWNsYXJhdG9yLmlkLnR5cGUgIT0gXCJJZGVudGlmaWVyXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgZGVjbGFyYXRvci5pZC50eXBlLCBub2RlTG9jYXRpb24oZGVjbGFyYXRvci5pZCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGlmIChkZWNsYXJhdG9yLmluaXQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJpbml0aWFsaXplZCBpdGVyYXRpb24gYmluZGluZ1wiLCBub2RlTG9jYXRpb24oZGVjbGFyYXRvciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGlmIChub2RlLmJvZHkudHlwZSAhPSBcIkJsb2NrU3RhdGVtZW50XCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJmb3Itb2Ygd2l0aG91dCBibG9jayBib2R5XCIsIG5vZGVMb2NhdGlvbihub2RlLmJvZHksIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCBjb2xsZWN0aW9uVHlwZSA9IGl0ZXJhdGlvbk9wZXJhbmRUeXBlKGtub3duRXhwcmVzc2lvblR5cGUobm9kZS5yaWdodCwgY29udGV4dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpKVxuXG4gIGlmIChjb2xsZWN0aW9uVHlwZT8ua2luZCA9PSBcIk1hcFR5cGVcIiB8fCBjb2xsZWN0aW9uVHlwZT8ua2luZCA9PSBcIk9yZGVyZWRNYXBUeXBlXCIpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibWFwIGl0ZXJhdGlvbiB3aXRob3V0IGtleS92YWx1ZSBwYWlyIGJpbmRpbmdcIiwgbm9kZUxvY2F0aW9uKG5vZGUucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGlmICghY29sbGVjdGlvblR5cGUgfHwgY29sbGVjdGlvblR5cGUua2luZCAhPSBcIkxpc3RUeXBlXCIpIHtcbiAgICByZXR1cm4gbWlzc2luZ1R5cGUobGFuZ3VhZ2UsIFwiSXRlcmF0aW9uIGNvbGxlY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUucmlnaHQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGJpbmRpbmdMb2NhdGlvbiA9IGlkZW50aWZpZXJMb2NhdGlvbihkZWNsYXJhdG9yLmlkLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBpbmZlcnJlZFR5cGUgPSBjb2xsZWN0aW9uVHlwZS5lbGVtZW50VHlwZVxuICBjb25zdCBiaW5kaW5nVHlwZSA9IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiICYmIGRlY2xhcmF0b3IuaWQudHlwZUFubm90YXRpb25cbiAgICA/IGNvbnZlcnRUeXBlU2NyaXB0VHlwZShkZWNsYXJhdG9yLmlkLnR5cGVBbm5vdGF0aW9uLCBgSXRlcmF0aW9uIGJpbmRpbmcgJyR7ZGVjbGFyYXRvci5pZC5uYW1lfSdgLCBiaW5kaW5nTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsXG4gICAgICBjb250ZXh0LnJlY29yZE5hbWVzLCBjb250ZXh0LnR5cGVQYXJhbWV0ZXJzKVxuICAgIDogaXRlcmF0aW9uQmluZGluZ1R5cGUoaW5mZXJyZWRUeXBlLCBiaW5kaW5nTG9jYXRpb24pXG4gIGNvbnN0IHZhbHVlQmluZGluZyA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlZhbHVlQmluZGluZ1wiKSxcbiAgICBsb2NhdGlvbjogYmluZGluZ0xvY2F0aW9uLFxuICAgIG11dGFibGU6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSksXG4gICAgbmFtZTogZGVjbGFyYXRvci5pZC5uYW1lLFxuICAgIHR5cGU6IGJpbmRpbmdUeXBlXG4gIH0sIHtuYW1lOiBiaW5kaW5nTG9jYXRpb259KVxuICBjb25zdCBib2R5Q29udGV4dCA9IHsuLi5jb250ZXh0LCBiaW5kaW5nczogbmV3IE1hcChjb250ZXh0LmJpbmRpbmdzKX1cblxuICBib2R5Q29udGV4dC5iaW5kaW5ncy5zZXQoZGVjbGFyYXRvci5pZC5uYW1lLCBiaW5kaW5nVHlwZSlcbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGJvZHk6IGNvbnZlcnRCbG9jayhub2RlLmJvZHksIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGJvZHlDb250ZXh0KSxcbiAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJGb3JFYWNoU3RhdGVtZW50XCIpLFxuICAgIGxpc3Q6IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUucmlnaHQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSxcbiAgICBsb2NhdGlvbixcbiAgICB2YWx1ZUJpbmRpbmdcbiAgfSwge1xuICAgIG9wZXJhdG9yOiB0b2tlbkxvY2F0aW9uKG5vZGUsIFwib2ZcIiwgbm9kZS5sZWZ0LmVuZCA/PyBub2RlLnN0YXJ0ID8/IDAsIG5vZGUucmlnaHQuc3RhcnQgPz8gbm9kZS5lbmQgPz8gc291cmNlLmxlbmd0aCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgQmFiZWwgYmxvY2sgb3Igbm9ybWFsaXplZCBzaW5nbGUtc3RhdGVtZW50IGJvZHkuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5CbG9ja1N0YXRlbWVudCB8IGltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdGF0ZW1lbnRbXX0gaW5wdXQgLSBQYXJzZXIgYmxvY2sgb3Igc3RhdGVtZW50cy5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNhbm9uaWNhbFplcm9SZXF1aXJlZCAtIFdoZXRoZXIgZ2VuZXJhdGVkIHNjYWxhciBvdXRwdXQgbWF5IGNvbnRhaW4gc2lnbmVkIHplcm8uXG4gKiBAcGFyYW0ge0phdmFTY3JpcHRDb252ZXJzaW9uQ29udGV4dH0gY29udGV4dCAtIFR5cGVkIGxleGljYWwgY29udmVyc2lvbiBjb250ZXh0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gW2xvY2F0aW9uXSAtIExvY2F0aW9uIGZvciBhIHN0YXRlbWVudC1hcnJheSBibG9jay5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gU2VtYW50aWMgYmxvY2suXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRCbG9jayhpbnB1dCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dCwgbG9jYXRpb24pIHtcbiAgY29uc3Qgc3RhdGVtZW50cyA9IEFycmF5LmlzQXJyYXkoaW5wdXQpID8gaW5wdXQgOiBpbnB1dC5ib2R5XG4gIGNvbnN0IGRpcmVjdGl2ZXMgPSBBcnJheS5pc0FycmF5KGlucHV0KSA/IFtdIDogaW5wdXQuZGlyZWN0aXZlc1xuICBjb25zdCBibG9ja0xvY2F0aW9uID0gbG9jYXRpb24gPz8gbm9kZUxvY2F0aW9uKC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkJsb2NrU3RhdGVtZW50fSAqLyAoaW5wdXQpLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBsZXhpY2FsVmFsdWVOYW1lcyA9IG5ldyBTZXQoY29udGV4dC5sZXhpY2FsVmFsdWVOYW1lcylcblxuICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBzdGF0ZW1lbnRzKSB7XG4gICAgaWYgKHN0YXRlbWVudC50eXBlICE9IFwiVmFyaWFibGVEZWNsYXJhdGlvblwiKSBjb250aW51ZVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRvciBvZiBzdGF0ZW1lbnQuZGVjbGFyYXRpb25zKSB7XG4gICAgICBpZiAoZGVjbGFyYXRvci5pZC50eXBlID09IFwiSWRlbnRpZmllclwiKSBsZXhpY2FsVmFsdWVOYW1lcy5hZGQoZGVjbGFyYXRvci5pZC5uYW1lKVxuICAgIH1cbiAgfVxuICBjb25zdCBibG9ja0NvbnRleHQgPSB7Li4uY29udGV4dCwgbGV4aWNhbFZhbHVlTmFtZXN9XG5cbiAgaWYgKGRpcmVjdGl2ZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJkaXJlY3RpdmVcIiwgbm9kZUxvY2F0aW9uKGRpcmVjdGl2ZXNbMF0sIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBraW5kOiBcIkJsb2NrXCIsXG4gICAgbG9jYXRpb246IGJsb2NrTG9jYXRpb24sXG4gICAgc3RhdGVtZW50czogc3RhdGVtZW50cy5tYXAoKHN0YXRlbWVudCkgPT4gY29udmVydFN0YXRlbWVudChzdGF0ZW1lbnQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGJsb2NrQ29udGV4dCkpXG4gIH1cbn1cblxuLyoqXG4gKiBSZWFkcyBKYXZhU2NyaXB0IEpTRG9jIHR5cGVzIGZyb20gYSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IG5vZGUgLSBCYWJlbCBmdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb3duZXJJZF0gLSBTdGFibGUgZGVjbGFyYXRpb24gaWRlbnRpdHkgZm9yIHR5cGUtcGFyYW1ldGVyIElEcy5cbiAqIEByZXR1cm5zIHt7cGFyYW1ldGVyczogTWFwPHN0cmluZywge2xvY2F0aW9uOiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgc291cmNlVHlwZTogc3RyaW5nfT4sIHJldHVyblR5cGU6IHtsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNvdXJjZVR5cGU6IHN0cmluZ30gfCB1bmRlZmluZWQsIHR5cGVQYXJhbWV0ZXJzPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcltdfX0gUGFyc2VkIHR5cGVzLlxuICovXG5mdW5jdGlvbiBqc2RvY1R5cGVzKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UsIG93bmVySWQpIHtcbiAgY29uc3QgY29tbWVudCA9IG5vZGUubGVhZGluZ0NvbW1lbnRzPy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS50eXBlID09IFwiQ29tbWVudEJsb2NrXCIgJiYgY2FuZGlkYXRlLnZhbHVlLnN0YXJ0c1dpdGgoXCIqXCIpKVxuXG4gIGlmICghY29tbWVudCkgbWlzc2luZ1R5cGUoXCJqYXZhc2NyaXB0XCIsIGBGdW5jdGlvbiAnJHtub2RlLmlkPy5uYW1lID8/IFwiYW5vbnltb3VzXCJ9J2AsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcblxuICBjb25zdCBjb21tZW50QmxvY2sgPSAvKiogQHR5cGUge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Db21tZW50QmxvY2t9ICovIChjb21tZW50KVxuICBjb25zdCBibG9jayA9IHBhcnNlQ29tbWVudChgLyoke2NvbW1lbnRCbG9jay52YWx1ZX0qL2ApWzBdXG4gIGNvbnN0IHBhcmFtZXRlclRhZ3MgPSBibG9jay50YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwicGFyYW1cIilcbiAgY29uc3QgcmV0dXJuVGFncyA9IGJsb2NrLnRhZ3MuZmlsdGVyKCh0YWcpID0+IHRhZy50YWcgPT0gXCJyZXR1cm5zXCIgfHwgdGFnLnRhZyA9PSBcInJldHVyblwiKVxuICBjb25zdCB0eXBlUGFyYW1ldGVycyA9IGpzZG9jVHlwZVBhcmFtZXRlcnMoY29tbWVudEJsb2NrLCBibG9jay50YWdzLCBvd25lcklkLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChuZXcgU2V0KHBhcmFtZXRlclRhZ3MubWFwKCh0YWcpID0+IHRhZy5uYW1lKSkuc2l6ZSAhPSBwYXJhbWV0ZXJUYWdzLmxlbmd0aCkge1xuICAgIGNvbnN0IGR1cGxpY2F0ZSA9IHBhcmFtZXRlclRhZ3MuZmluZCgodGFnLCBpbmRleCkgPT4gcGFyYW1ldGVyVGFncy5maW5kSW5kZXgoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT0gdGFnLm5hbWUpICE9IGluZGV4KVxuXG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiamF2YXNjcmlwdFwiLCBcImR1cGxpY2F0ZSBAcGFyYW0gYW5ub3RhdGlvblwiLCBkdXBsaWNhdGVcbiAgICAgID8gY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnRCbG9jaywgZHVwbGljYXRlLCBcIm5hbWVcIiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIDogbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGlmIChyZXR1cm5UYWdzLmxlbmd0aCA+IDEpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJqYXZhc2NyaXB0XCIsIFwiZHVwbGljYXRlIEByZXR1cm4gYW5ub3RhdGlvblwiLFxuICAgICAgY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnRCbG9jaywgcmV0dXJuVGFnc1sxXSwgXCJ0eXBlXCIsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IHBhcmFtZXRlcnMgPSBuZXcgTWFwKHBhcmFtZXRlclRhZ3MubWFwKCh0YWcpID0+IFt0YWcubmFtZSwge1xuICAgIGxvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudEJsb2NrLCB0YWcsIFwidHlwZVwiLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBzb3VyY2VUeXBlOiB0YWcudHlwZVxuICB9XSkpXG4gIGNvbnN0IHJldHVyblRhZyA9IHJldHVyblRhZ3NbMF1cblxuICByZXR1cm4ge1xuICAgIHBhcmFtZXRlcnMsXG4gICAgcmV0dXJuVHlwZTogcmV0dXJuVGFnID8ge2xvY2F0aW9uOiBjb21tZW50VGFnTG9jYXRpb24oY29tbWVudEJsb2NrLCByZXR1cm5UYWcsIFwidHlwZVwiLCBmaWxlbmFtZSwgc291cmNlKSwgc291cmNlVHlwZTogcmV0dXJuVGFnLnR5cGV9IDogdW5kZWZpbmVkLFxuICAgIC4uLih0eXBlUGFyYW1ldGVycyA/IHt0eXBlUGFyYW1ldGVyc30gOiB7fSlcbiAgfVxufVxuXG4vKipcbiAqIFJlYWRzIGV4YWN0IHVuYm91bmRlZCBpbnZhcmlhbnQgYEB0ZW1wbGF0ZSBOYW1lYCBkZWNsYXJhdGlvbnMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Db21tZW50QmxvY2t9IGNvbW1lbnQgLSBQYXJzZXItb3duZWQgSlNEb2MgYmxvY2suXG4gKiBAcGFyYW0ge2ltcG9ydChcImNvbW1lbnQtcGFyc2VyXCIpLlNwZWNbXX0gdGFncyAtIFBhcnNlZCB0YWdzLlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IG93bmVySWQgLSBTdGFibGUgZGVjbGFyYXRpb24gaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXJbXSB8IHVuZGVmaW5lZH0gT3JkZXJlZCBwYXJhbWV0ZXJzIHdoZW4gcHJlc2VudC5cbiAqL1xuZnVuY3Rpb24ganNkb2NUeXBlUGFyYW1ldGVycyhjb21tZW50LCB0YWdzLCBvd25lcklkLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IG1hbGZvcm1lZCA9IHRhZ3MuZmluZCgodGFnKSA9PiB0YWcudGFnLnN0YXJ0c1dpdGgoXCJ0ZW1wbGF0ZVwiKSAmJiB0YWcudGFnICE9IFwidGVtcGxhdGVcIilcblxuICBpZiAobWFsZm9ybWVkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJqYXZhc2NyaXB0XCIsIFwidW5zdXBwb3J0ZWQgdHlwZSBwYXJhbWV0ZXIgdmFyaWFuY2VcIiwgY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIG1hbGZvcm1lZCwgXCJuYW1lXCIsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCB0ZW1wbGF0ZVRhZ3MgPSB0YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwidGVtcGxhdGVcIilcblxuICBpZiAodGVtcGxhdGVUYWdzLmxlbmd0aCA9PSAwKSByZXR1cm4gdW5kZWZpbmVkXG4gIGlmICghb3duZXJJZCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiamF2YXNjcmlwdFwiLCBcInR5cGUgcGFyYW1ldGVyIG91dHNpZGUgYSBkZWNsYXJhdGlvblwiLFxuICAgIG5vZGVMb2NhdGlvbigvKiogQHR5cGUge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Ob2RlfSAqLyAoLyoqIEB0eXBlIHt1bmtub3dufSAqLyAoY29tbWVudCkpLCBmaWxlbmFtZSwgc291cmNlKSlcblxuICByZXR1cm4gdGVtcGxhdGVUYWdzLm1hcCgodGFnLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gY29tbWVudFRhZ0xvY2F0aW9uKGNvbW1lbnQsIHRhZywgXCJuYW1lXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAoIS9eW0EtWmEtel8kXVtBLVphLXowLTlfJF0qJC91LnRlc3QodGFnLm5hbWUpIHx8IHRhZy50eXBlIHx8IHRhZy5kZXNjcmlwdGlvbikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiamF2YXNjcmlwdFwiLCBcImJvdW5kZWQsIGRlZmF1bHRlZCwgb3IgbWFsZm9ybWVkIHR5cGUgcGFyYW1ldGVyXCIsIGxvY2F0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtpZDogYCR7b3duZXJJZH06dHlwZToke2luZGV4fWAsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlR5cGVQYXJhbWV0ZXJcIiksIGxvY2F0aW9uLCBuYW1lOiB0YWcubmFtZX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gIH0pXG59XG5cbi8qKlxuICogUmVhZHMgYW4gb3B0aW9uYWwgY2xhc3MtbGV2ZWwgSlNEb2MgdGVtcGxhdGUgYmxvY2suXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBub2RlIC0gQ2xhc3MgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gb3duZXJJZCAtIFJlY29yZCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcltdIHwgdW5kZWZpbmVkfSBPcmRlcmVkIHBhcmFtZXRlcnMuXG4gKi9cbmZ1bmN0aW9uIGNsYXNzSnNkb2NUeXBlUGFyYW1ldGVycyhub2RlLCBvd25lcklkLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGNvbW1lbnQgPSAvKiogQHR5cGUge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Db21tZW50QmxvY2sgfCB1bmRlZmluZWR9ICovIChcbiAgICBub2RlLmxlYWRpbmdDb21tZW50cz8uZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUudHlwZSA9PSBcIkNvbW1lbnRCbG9ja1wiICYmIGNhbmRpZGF0ZS52YWx1ZS5zdGFydHNXaXRoKFwiKlwiKSkpXG5cbiAgaWYgKCFjb21tZW50KSByZXR1cm4gdW5kZWZpbmVkXG4gIGNvbnN0IGJsb2NrID0gcGFyc2VDb21tZW50KGAvKiR7Y29tbWVudC52YWx1ZX0qL2ApWzBdXG5cbiAgcmV0dXJuIGpzZG9jVHlwZVBhcmFtZXRlcnMoY29tbWVudCwgYmxvY2sudGFncywgb3duZXJJZCwgZmlsZW5hbWUsIHNvdXJjZSlcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyBhIHN1cHBvcnRlZCBKYXZhU2NyaXB0IEpTRG9jIHNjYWxhciB0eXBlIHNwZWxsaW5nLlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHNvdXJjZVR5cGUgLSBTb3VyY2UtbGFuZ3VhZ2UgdHlwZS5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gbGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gU291cmNlIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHBhcnNlciBpbnB1dC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFt0eXBlTG9jYXRpb25dIC0gRXhhY3QgdHlwZSB0b2tlbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IFtyZWNvcmROYW1lc10gLSBOb21pbmFsIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcj59IFt0eXBlUGFyYW1ldGVyc10gLSBEZWNsYXJhdGlvbi1zY29wZWQgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY1ZhbHVlVHlwZX0gU2VtYW50aWMgdHlwZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFR5cGUoc291cmNlVHlwZSwgbGFuZ3VhZ2UsIHN1YmplY3QsIGxvY2F0aW9uLCBzb3VyY2UsIHR5cGVMb2NhdGlvbiA9IGxvY2F0aW9uLCByZWNvcmROYW1lcyA9IG5ldyBNYXAoKSwgdHlwZVBhcmFtZXRlcnMgPSBuZXcgTWFwKCkpIHtcbiAgaWYgKGxhbmd1YWdlICE9IFwiamF2YXNjcmlwdFwiKSByZXR1cm4gcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUobGFuZ3VhZ2UsIHNvdXJjZVR5cGUsIHN1YmplY3QsIGxvY2F0aW9uLCB0eXBlTG9jYXRpb24pXG5cbiAgcmV0dXJuIGRvY3VtZW50ZWRWYWx1ZVR5cGUoe2xhbmd1YWdlLCBsb2NhdGlvbjogdHlwZUxvY2F0aW9uLCBvd25lckxvY2F0aW9uOiBsb2NhdGlvbiwgcmVjb3JkczogcmVjb3JkTmFtZXMsIHNvdXJjZSwgc291cmNlVHlwZSwgc3ViamVjdCwgdHlwZVBhcmFtZXRlcnN9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBKYXZhU2NyaXB0IGZ1bmN0aW9uIHJldHVybiBhbm5vdGF0aW9uLlxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHNvdXJjZVR5cGUgLSBKU0RvYyB0eXBlIHNwZWxsaW5nLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBUeXBlZCBmdW5jdGlvbiByZXR1cm4uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBsb2NhdGlvbiAtIEZ1bmN0aW9uIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHBhcnNlciBpbnB1dC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFt0eXBlTG9jYXRpb25dIC0gRXhhY3QgYW5ub3RhdGlvbiBsb2NhdGlvbi5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IFtyZWNvcmROYW1lc10gLSBOb21pbmFsIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcj59IFt0eXBlUGFyYW1ldGVyc10gLSBEZWNsYXJhdGlvbi1zY29wZWQgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gU2VtYW50aWMgcmV0dXJuIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRSZXR1cm5UeXBlKHNvdXJjZVR5cGUsIGxhbmd1YWdlLCBzdWJqZWN0LCBsb2NhdGlvbiwgc291cmNlLCB0eXBlTG9jYXRpb24gPSBsb2NhdGlvbiwgcmVjb3JkTmFtZXMgPSBuZXcgTWFwKCksIHR5cGVQYXJhbWV0ZXJzID0gbmV3IE1hcCgpKSB7XG4gIGlmIChzb3VyY2VUeXBlID09IFwidm9pZFwiKSByZXR1cm4gcmVxdWlyZVNvdXJjZVJldHVyblR5cGUobGFuZ3VhZ2UsIHNvdXJjZVR5cGUsIHN1YmplY3QsIGxvY2F0aW9uLCB0eXBlTG9jYXRpb24pXG5cbiAgcmV0dXJuIGNvbnZlcnRUeXBlKHNvdXJjZVR5cGUsIGxhbmd1YWdlLCBzdWJqZWN0LCBsb2NhdGlvbiwgc291cmNlLCB0eXBlTG9jYXRpb24sIHJlY29yZE5hbWVzLCB0eXBlUGFyYW1ldGVycylcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhhY3QgVHlwZVNjcmlwdCBzY2FsYXIga2V5d29yZCBhbm5vdGF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuVHlwZUFubm90YXRpb24gfCBpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuVFNUeXBlQW5ub3RhdGlvbiB8IGltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Ob29wIHwgbnVsbCB8IHVuZGVmaW5lZH0gYW5ub3RhdGlvbiAtIFR5cGUgYW5ub3RhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgc3ViamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IG93bmVyTG9jYXRpb24gLSBPd25pbmcgZGVjbGFyYXRpb24gbG9jYXRpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uPn0gW3JlY29yZE5hbWVzXSAtIE5vbWluYWwgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUGFyYW1ldGVyPn0gW3R5cGVQYXJhbWV0ZXJzXSAtIERlY2xhcmF0aW9uLXNjb3BlZCBwYXJhbWV0ZXJzLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljVmFsdWVUeXBlfSBTZW1hbnRpYyB0eXBlLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0VHlwZVNjcmlwdFR5cGUoYW5ub3RhdGlvbiwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMgPSBuZXcgTWFwKCksIHR5cGVQYXJhbWV0ZXJzID0gbmV3IE1hcCgpKSB7XG4gIGlmICghYW5ub3RhdGlvbikgcmV0dXJuIG1pc3NpbmdUeXBlKFwidHlwZXNjcmlwdFwiLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uKVxuICBpZiAoYW5ub3RhdGlvbi50eXBlICE9IFwiVFNUeXBlQW5ub3RhdGlvblwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciB0eXBlXCIsIG5vZGVMb2NhdGlvbihhbm5vdGF0aW9uLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiBjb252ZXJ0VHlwZVNjcmlwdFZhbHVlVHlwZU5vZGUoYW5ub3RhdGlvbi50eXBlQW5ub3RhdGlvbiwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJzKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBib3VuZGVkIHJlY3Vyc2l2ZSBUeXBlU2NyaXB0IHZhbHVlLXR5cGUgdHJlZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlRTVHlwZX0gdHlwZU5vZGUgLSBQYXJzZXItb3duZWQgdHlwZSBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBUeXBlZCBzdWJqZWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gb3duZXJMb2NhdGlvbiAtIE93bmluZyBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSBbcmVjb3JkTmFtZXNdIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVQYXJhbWV0ZXI+fSBbdHlwZVBhcmFtZXRlcnNdIC0gRGVjbGFyYXRpb24tc2NvcGVkIHBhcmFtZXRlcnMuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNWYWx1ZVR5cGV9IFNlbWFudGljIHZhbHVlIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUeXBlU2NyaXB0VmFsdWVUeXBlTm9kZSh0eXBlTm9kZSwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMgPSBuZXcgTWFwKCksIHR5cGVQYXJhbWV0ZXJzID0gbmV3IE1hcCgpKSB7XG4gIGNvbnN0IHNvdXJjZVR5cGUgPSB0eXBlTm9kZS50eXBlID09IFwiVFNOdW1iZXJLZXl3b3JkXCIgPyBcIm51bWJlclwiIDpcbiAgICB0eXBlTm9kZS50eXBlID09IFwiVFNCb29sZWFuS2V5d29yZFwiID8gXCJib29sZWFuXCIgOiB0eXBlTm9kZS50eXBlID09IFwiVFNTdHJpbmdLZXl3b3JkXCIgPyBcInN0cmluZ1wiIDogdW5kZWZpbmVkXG5cbiAgaWYgKHNvdXJjZVR5cGUpIHtcbiAgICByZXR1cm4gcmVxdWlyZVNvdXJjZVNjYWxhclR5cGUoXCJ0eXBlc2NyaXB0XCIsIHNvdXJjZVR5cGUsIHN1YmplY3QsIG93bmVyTG9jYXRpb24sIG5vZGVMb2NhdGlvbih0eXBlTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgaWYgKHR5cGVOb2RlLnR5cGUgPT0gXCJUU1R5cGVSZWZlcmVuY2VcIiAmJiB0eXBlTm9kZS50eXBlTmFtZS50eXBlID09IFwiSWRlbnRpZmllclwiICYmICF0eXBlTm9kZS50eXBlUGFyYW1ldGVycyAmJlxuICAgIHR5cGVQYXJhbWV0ZXJzLmhhcyh0eXBlTm9kZS50eXBlTmFtZS5uYW1lKSkge1xuICAgIGNvbnN0IHBhcmFtZXRlciA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcn0gKi8gKHR5cGVQYXJhbWV0ZXJzLmdldCh0eXBlTm9kZS50eXBlTmFtZS5uYW1lKSlcblxuICAgIHJldHVybiB0eXBlVmFyaWFibGUoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChwYXJhbWV0ZXIuaWQpLCBub2RlTG9jYXRpb24odHlwZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGlmICh0eXBlTm9kZS50eXBlID09IFwiVFNUeXBlUmVmZXJlbmNlXCIgJiYgdHlwZU5vZGUudHlwZU5hbWUudHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJlxuICAgIHJlY29yZE5hbWVzLmhhcyh0eXBlTm9kZS50eXBlTmFtZS5uYW1lKSkge1xuICAgIGNvbnN0IGRlY2xhcmF0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9ufSAqLyAocmVjb3JkTmFtZXMuZ2V0KHR5cGVOb2RlLnR5cGVOYW1lLm5hbWUpKVxuXG4gICAgaWYgKGRlY2xhcmF0aW9uLmtpbmQgPT0gXCJFZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGlmICh0eXBlTm9kZS50eXBlUGFyYW1ldGVycykgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcImdlbmVyaWMgb3duZWQgcmVzb3VyY2UgdHlwZVwiLCBub2RlTG9jYXRpb24odHlwZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgcmV0dXJuIG93bmVkUmVzb3VyY2VUeXBlKGRlY2xhcmF0aW9uLmlkLCBub2RlTG9jYXRpb24odHlwZU5vZGUudHlwZU5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBpZiAoZGVjbGFyYXRpb24ua2luZCA9PSBcIkNsYXNzRGVjbGFyYXRpb25cIikge1xuICAgICAgaWYgKHR5cGVOb2RlLnR5cGVQYXJhbWV0ZXJzKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJ0eXBlc2NyaXB0XCIsIFwiZ2VuZXJpYyByZWZlcmVuY2UgY2xhc3MgdHlwZVwiLCBub2RlTG9jYXRpb24odHlwZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24odHlwZU5vZGUudHlwZU5hbWUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgICByZXR1cm4gZGVjbGFyYXRpb24ub3duZXJzaGlwPy5raW5kID09IFwib3duZWRSZXNvdXJjZVwiXG4gICAgICAgID8gb3duZWRSZWZlcmVuY2VUeXBlKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBsb2NhdGlvbilcbiAgICAgICAgOiByZWZlcmVuY2VUeXBlKC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBsb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgYXJndW1lbnRzXyA9IHR5cGVOb2RlLnR5cGVQYXJhbWV0ZXJzPy5wYXJhbXMubWFwKChwYXJhbWV0ZXIpID0+XG4gICAgICBjb252ZXJ0VHlwZVNjcmlwdFZhbHVlVHlwZU5vZGUocGFyYW1ldGVyLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcywgdHlwZVBhcmFtZXRlcnMpKVxuXG4gICAgcmV0dXJuIHJlY29yZFR5cGUoLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIG5vZGVMb2NhdGlvbih0eXBlTm9kZS50eXBlTmFtZSwgZmlsZW5hbWUsIHNvdXJjZSksIGFyZ3VtZW50c18pXG4gIH1cbiAgaWYgKHR5cGVOb2RlLnR5cGUgPT0gXCJUU1VuaW9uVHlwZVwiKSB7XG4gICAgaWYgKHR5cGVOb2RlLnR5cGVzLmxlbmd0aCAhPSAyIHx8IHR5cGVOb2RlLnR5cGVzWzFdLnR5cGUgIT0gXCJUU051bGxLZXl3b3JkXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcbiAgICAgICAgXCJ0eXBlc2NyaXB0XCIsXG4gICAgICAgIHR5cGVOb2RlLnR5cGVzLnNvbWUoKG1lbWJlcikgPT4gbWVtYmVyLnR5cGUgPT0gXCJUU051bGxLZXl3b3JkXCIpXG4gICAgICAgICAgPyBcImFyYml0cmFyeSB1bmlvbiB0eXBlXCJcbiAgICAgICAgICA6IFwidW5zdXBwb3J0ZWQgY29sbGVjdGlvbiBvciBzY2FsYXIgdHlwZVwiLFxuICAgICAgICBub2RlTG9jYXRpb24odHlwZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgICApXG4gICAgfVxuICAgIGNvbnN0IHZhbHVlTm9kZSA9IHR5cGVOb2RlLnR5cGVzWzBdXG5cbiAgICByZXR1cm4gb3B0aW9uYWxUeXBlKFxuICAgICAgY29udmVydFR5cGVTY3JpcHRWYWx1ZVR5cGVOb2RlKHZhbHVlTm9kZSwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJzKSxcbiAgICAgIG5vZGVMb2NhdGlvbih0eXBlTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBub2RlTG9jYXRpb24odmFsdWVOb2RlLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIClcbiAgfVxuICBpZiAodHlwZU5vZGUudHlwZSA9PSBcIlRTVHlwZU9wZXJhdG9yXCIgJiYgdHlwZU5vZGUub3BlcmF0b3IgPT0gXCJyZWFkb25seVwiICYmIHR5cGVOb2RlLnR5cGVBbm5vdGF0aW9uLnR5cGUgPT0gXCJUU0FycmF5VHlwZVwiKSB7XG4gICAgY29uc3QgZWxlbWVudE5vZGUgPSB0eXBlTm9kZS50eXBlQW5ub3RhdGlvbi5lbGVtZW50VHlwZVxuXG4gICAgcmV0dXJuIGxpc3RUeXBlKFxuICAgICAgY29udmVydFR5cGVTY3JpcHRWYWx1ZVR5cGVOb2RlKGVsZW1lbnROb2RlLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcywgdHlwZVBhcmFtZXRlcnMpLFxuICAgICAgbm9kZUxvY2F0aW9uKHR5cGVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIG5vZGVMb2NhdGlvbihlbGVtZW50Tm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICApXG4gIH1cbiAgaWYgKHR5cGVOb2RlLnR5cGUgPT0gXCJUU1R5cGVSZWZlcmVuY2VcIiAmJiB0eXBlTm9kZS50eXBlTmFtZS50eXBlID09IFwiSWRlbnRpZmllclwiICYmXG4gICAgW1wiUmVhZG9ubHlBcnJheVwiLCBcIlJlYWRvbmx5TWFwXCJdLmluY2x1ZGVzKHR5cGVOb2RlLnR5cGVOYW1lLm5hbWUpKSB7XG4gICAgY29uc3QgcGFyYW1ldGVycyA9IHR5cGVOb2RlLnR5cGVQYXJhbWV0ZXJzPy5wYXJhbXMgPz8gW11cblxuICAgIGlmICh0eXBlTm9kZS50eXBlTmFtZS5uYW1lID09IFwiUmVhZG9ubHlBcnJheVwiICYmIHBhcmFtZXRlcnMubGVuZ3RoID09IDEpIHtcbiAgICAgIHJldHVybiBsaXN0VHlwZShcbiAgICAgICAgY29udmVydFR5cGVTY3JpcHRWYWx1ZVR5cGVOb2RlKHBhcmFtZXRlcnNbMF0sIHN1YmplY3QsIG93bmVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzLCB0eXBlUGFyYW1ldGVycyksXG4gICAgICAgIG5vZGVMb2NhdGlvbih0eXBlTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIG5vZGVMb2NhdGlvbihwYXJhbWV0ZXJzWzBdLCBmaWxlbmFtZSwgc291cmNlKVxuICAgICAgKVxuICAgIH1cbiAgICBpZiAodHlwZU5vZGUudHlwZU5hbWUubmFtZSA9PSBcIlJlYWRvbmx5TWFwXCIgJiYgcGFyYW1ldGVycy5sZW5ndGggPT0gMikge1xuICAgICAgY29uc3Qga2V5VHlwZSA9IGNvbnZlcnRUeXBlU2NyaXB0VmFsdWVUeXBlTm9kZShwYXJhbWV0ZXJzWzBdLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcywgdHlwZVBhcmFtZXRlcnMpXG5cbiAgICAgIGlmIChrZXlUeXBlLmtpbmQgIT0gXCJUeXBlUmVmZXJlbmNlXCIpIHtcbiAgICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcIm1hcCBrZXkgdHlwZSBvdGhlciB0aGFuIHN0cmluZ1wiLCBub2RlTG9jYXRpb24ocGFyYW1ldGVyc1swXSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG4gICAgICByZXR1cm4gbWFwVHlwZShcbiAgICAgICAga2V5VHlwZSxcbiAgICAgICAgY29udmVydFR5cGVTY3JpcHRWYWx1ZVR5cGVOb2RlKHBhcmFtZXRlcnNbMV0sIHN1YmplY3QsIG93bmVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIHJlY29yZE5hbWVzLCB0eXBlUGFyYW1ldGVycyksXG4gICAgICAgIG5vZGVMb2NhdGlvbih0eXBlTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIG5vZGVMb2NhdGlvbihwYXJhbWV0ZXJzWzBdLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgbm9kZUxvY2F0aW9uKHBhcmFtZXRlcnNbMV0sIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgICApXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcInVuc3VwcG9ydGVkIGNvbGxlY3Rpb24gb3Igc2NhbGFyIHR5cGVcIiwgbm9kZUxvY2F0aW9uKHR5cGVOb2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhhY3QgVHlwZVNjcmlwdCBmdW5jdGlvbiByZXR1cm4gYW5ub3RhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlR5cGVBbm5vdGF0aW9uIHwgaW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlRTVHlwZUFubm90YXRpb24gfCBpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9vcCB8IG51bGwgfCB1bmRlZmluZWR9IGFubm90YXRpb24gLSBSZXR1cm4gYW5ub3RhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzdWJqZWN0IC0gVHlwZWQgZnVuY3Rpb24gcmV0dXJuLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gb3duZXJMb2NhdGlvbiAtIEZ1bmN0aW9uIGxvY2F0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IFtyZWNvcmROYW1lc10gLSBOb21pbmFsIGRlY2xhcmF0aW9ucyBieSBzb3VyY2UgbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVBhcmFtZXRlcj59IFt0eXBlUGFyYW1ldGVyc10gLSBEZWNsYXJhdGlvbi1zY29wZWQgcGFyYW1ldGVycy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY0Z1bmN0aW9uUmV0dXJuVHlwZX0gU2VtYW50aWMgcmV0dXJuIHR5cGUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRUeXBlU2NyaXB0UmV0dXJuVHlwZShhbm5vdGF0aW9uLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcyA9IG5ldyBNYXAoKSwgdHlwZVBhcmFtZXRlcnMgPSBuZXcgTWFwKCkpIHtcbiAgaWYgKCFhbm5vdGF0aW9uKSByZXR1cm4gcmVxdWlyZVNvdXJjZVJldHVyblR5cGUoXCJ0eXBlc2NyaXB0XCIsIHVuZGVmaW5lZCwgc3ViamVjdCwgb3duZXJMb2NhdGlvbilcbiAgaWYgKGFubm90YXRpb24udHlwZSAhPSBcIlRTVHlwZUFubm90YXRpb25cIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInR5cGVzY3JpcHRcIiwgXCJ1bnN1cHBvcnRlZCByZXR1cm4gdHlwZVwiLCBub2RlTG9jYXRpb24oYW5ub3RhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgdHlwZU5vZGUgPSBhbm5vdGF0aW9uLnR5cGVBbm5vdGF0aW9uXG5cbiAgaWYgKHR5cGVOb2RlLnR5cGUgPT0gXCJUU1ZvaWRLZXl3b3JkXCIpIHtcbiAgICByZXR1cm4gcmVxdWlyZVNvdXJjZVJldHVyblR5cGUoXCJ0eXBlc2NyaXB0XCIsIFwidm9pZFwiLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCBub2RlTG9jYXRpb24odHlwZU5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG5cbiAgcmV0dXJuIGNvbnZlcnRUeXBlU2NyaXB0VmFsdWVUeXBlTm9kZSh0eXBlTm9kZSwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJzKVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBuYXRpdmUgdW5ib3VuZGVkIGludmFyaWFudCBUeXBlU2NyaXB0IHBhcmFtZXRlciBsaXN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuVFNUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBudWxsIHwgdW5kZWZpbmVkfSBkZWNsYXJhdGlvbiAtIFBhcnNlci1vd25lZCBsaXN0LlxuICogQHBhcmFtIHtzdHJpbmd9IG93bmVySWQgLSBTdGFibGUgb3duaW5nIGRlY2xhcmF0aW9uIGlkZW50aXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5UeXBlUGFyYW1ldGVyW10gfCB1bmRlZmluZWR9IFNlbWFudGljIHBhcmFtZXRlcnMuXG4gKi9cbmZ1bmN0aW9uIHR5cGVTY3JpcHRUeXBlUGFyYW1ldGVycyhkZWNsYXJhdGlvbiwgb3duZXJJZCwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIWRlY2xhcmF0aW9uKSByZXR1cm4gdW5kZWZpbmVkXG5cbiAgcmV0dXJuIGRlY2xhcmF0aW9uLnBhcmFtcy5tYXAoKHBhcmFtZXRlciwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAocGFyYW1ldGVyLmNvbnN0cmFpbnQgfHwgcGFyYW1ldGVyLmRlZmF1bHQgfHwgUmVmbGVjdC5nZXQocGFyYW1ldGVyLCBcImluXCIpIHx8IFJlZmxlY3QuZ2V0KHBhcmFtZXRlciwgXCJvdXRcIikgfHxcbiAgICAgIFJlZmxlY3QuZ2V0KHBhcmFtZXRlciwgXCJjb25zdFwiKSB8fCB0eXBlb2YgcGFyYW1ldGVyLm5hbWUgIT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcImJvdW5kZWQsIGRlZmF1bHRlZCwgdmFyaWFudCwgb3IgY29uc3QgdHlwZSBwYXJhbWV0ZXJcIiwgbG9jYXRpb24pXG4gICAgfVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2lkOiBgJHtvd25lcklkfTp0eXBlOiR7aW5kZXh9YCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiVHlwZVBhcmFtZXRlclwiKSwgbG9jYXRpb24sIG5hbWU6IHBhcmFtZXRlci5uYW1lfSwge25hbWU6IGxvY2F0aW9ufSlcbiAgfSlcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHN1cHBvcnRlZCBmdW5jdGlvbiBzaWduYXR1cmUgYmVmb3JlIGFueSBib2R5IGV4cHJlc3Npb25zLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gbm9kZSAtIEJhYmVsIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgc291cmNlIG5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gb3duZXJJZCAtIFN0YWJsZSBmdW5jdGlvbiBpZGVudGl0eS5cbiAqIEByZXR1cm5zIHtKYXZhU2NyaXB0RnVuY3Rpb25TaWduYXR1cmV9IFNlbWFudGljIGZ1bmN0aW9uIHNpZ25hdHVyZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uU2lnbmF0dXJlKG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcywgb3duZXJJZCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmICghbm9kZS5pZCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImFub255bW91cyBmdW5jdGlvblwiLCBsb2NhdGlvbilcbiAgaWYgKG5vZGUuYXN5bmMpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJhc3luYyBmdW5jdGlvblwiLCBsb2NhdGlvbilcbiAgaWYgKG5vZGUuZ2VuZXJhdG9yKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiZ2VuZXJhdG9yIGZ1bmN0aW9uXCIsIGxvY2F0aW9uKVxuICBjb25zdCBuYXRpdmVUeXBlUGFyYW1ldGVycyA9IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiXG4gICAgPyB0eXBlU2NyaXB0VHlwZVBhcmFtZXRlcnMoLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuVFNUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBudWxsIHwgdW5kZWZpbmVkfSAqLyAobm9kZS50eXBlUGFyYW1ldGVycyksIG93bmVySWQsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgOiBub2RlLnR5cGVQYXJhbWV0ZXJzID8gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibmF0aXZlIGdlbmVyaWMgZnVuY3Rpb25cIiwgbm9kZUxvY2F0aW9uKG5vZGUudHlwZVBhcmFtZXRlcnMsIGZpbGVuYW1lLCBzb3VyY2UpKSA6IHVuZGVmaW5lZFxuICBjb25zdCBkb2N1bWVudGVkVHlwZXMgPSBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIiA/IGpzZG9jVHlwZXMobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSwgb3duZXJJZCkgOiB1bmRlZmluZWRcbiAgY29uc3QgdHlwZVBhcmFtZXRlcnNfID0gbmF0aXZlVHlwZVBhcmFtZXRlcnMgPz8gZG9jdW1lbnRlZFR5cGVzPy50eXBlUGFyYW1ldGVyc1xuICBjb25zdCB0eXBlUGFyYW1ldGVyTmFtZXMgPSBuZXcgTWFwKCh0eXBlUGFyYW1ldGVyc18gPz8gW10pLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlcl0pKVxuICBjb25zdCBwYXJhbWV0ZXJzID0gbm9kZS5wYXJhbXMubWFwKChwYXJhbWV0ZXIpID0+IHtcbiAgICBjb25zdCBwYXJhbWV0ZXJMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAocGFyYW1ldGVyLnR5cGUgIT0gXCJJZGVudGlmaWVyXCIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgcGFyYW1ldGVyLnR5cGUsIHBhcmFtZXRlckxvY2F0aW9uKVxuICAgIGlmIChwYXJhbWV0ZXIub3B0aW9uYWwpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJvcHRpb25hbCBwYXJhbWV0ZXJcIiwgcGFyYW1ldGVyTG9jYXRpb24pXG5cbiAgICBjb25zdCBkb2N1bWVudGVkVHlwZSA9IGRvY3VtZW50ZWRUeXBlcz8ucGFyYW1ldGVycy5nZXQocGFyYW1ldGVyLm5hbWUpXG4gICAgY29uc3QgdHlwZSA9IGxhbmd1YWdlID09IFwiamF2YXNjcmlwdFwiXG4gICAgICA/IGNvbnZlcnRUeXBlKGRvY3VtZW50ZWRUeXBlPy5zb3VyY2VUeXBlLCBsYW5ndWFnZSwgYFBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIHNvdXJjZSwgZG9jdW1lbnRlZFR5cGU/LmxvY2F0aW9uLCByZWNvcmROYW1lcywgdHlwZVBhcmFtZXRlck5hbWVzKVxuICAgICAgOiBjb252ZXJ0VHlwZVNjcmlwdFR5cGUocGFyYW1ldGVyLnR5cGVBbm5vdGF0aW9uLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlci5uYW1lfSdgLCBwYXJhbWV0ZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSwgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJOYW1lcylcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSxcbiAgICAgIGxvY2F0aW9uOiBwYXJhbWV0ZXJMb2NhdGlvbixcbiAgICAgIG5hbWU6IHBhcmFtZXRlci5uYW1lLFxuICAgICAgdHlwZVxuICAgIH0sIHtuYW1lOiBpZGVudGlmaWVyTG9jYXRpb24ocGFyYW1ldGVyLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH0pXG4gIGNvbnN0IGV4dHJhRG9jdW1lbnRlZFBhcmFtZXRlciA9IGRvY3VtZW50ZWRUeXBlcyAmJiBbLi4uZG9jdW1lbnRlZFR5cGVzLnBhcmFtZXRlcnMua2V5cygpXVxuICAgIC5maW5kKChuYW1lKSA9PiAhbm9kZS5wYXJhbXMuc29tZSgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIudHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJiBwYXJhbWV0ZXIubmFtZSA9PSBuYW1lKSlcblxuICBpZiAoZXh0cmFEb2N1bWVudGVkUGFyYW1ldGVyKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIGBhbm5vdGF0aW9uIGZvciB1bmtub3duIHBhcmFtZXRlciAnJHtleHRyYURvY3VtZW50ZWRQYXJhbWV0ZXJ9J2AsIGxvY2F0aW9uKVxuICBjb25zdCByZXR1cm5Bbm5vdGF0aW9uID0gbm9kZS5yZXR1cm5UeXBlXG4gIGNvbnN0IHJldHVyblR5cGUgPSBsYW5ndWFnZSA9PSBcImphdmFzY3JpcHRcIlxuICAgID8gY29udmVydFJldHVyblR5cGUoZG9jdW1lbnRlZFR5cGVzPy5yZXR1cm5UeXBlPy5zb3VyY2VUeXBlLCBsYW5ndWFnZSwgYEZ1bmN0aW9uICcke25vZGUuaWQubmFtZX0nIHJldHVybmAsIGxvY2F0aW9uLCBzb3VyY2UsIGRvY3VtZW50ZWRUeXBlcz8ucmV0dXJuVHlwZT8ubG9jYXRpb24sIHJlY29yZE5hbWVzLCB0eXBlUGFyYW1ldGVyTmFtZXMpXG4gICAgOiBjb252ZXJ0VHlwZVNjcmlwdFJldHVyblR5cGUocmV0dXJuQW5ub3RhdGlvbiwgYEZ1bmN0aW9uICcke25vZGUuaWQubmFtZX0nIHJldHVybmAsIGxvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcywgdHlwZVBhcmFtZXRlck5hbWVzKVxuICByZXR1cm4ge1xuICAgIGxvY2F0aW9uLFxuICAgIG5hbWU6IG5vZGUuaWQubmFtZSxcbiAgICBuYW1lTG9jYXRpb246IGlkZW50aWZpZXJMb2NhdGlvbihub2RlLmlkLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBwYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGUsXG4gICAgLi4uKHR5cGVQYXJhbWV0ZXJzXyA/IHt0eXBlUGFyYW1ldGVyczogdHlwZVBhcmFtZXRlcnNffSA6IHt9KVxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgYSBzdXBwb3J0ZWQgZnVuY3Rpb24gYm9keSB1c2luZyBhbGwgYWxyZWFkeS1wcm92ZWQgc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkZ1bmN0aW9uRGVjbGFyYXRpb259IG5vZGUgLSBCYWJlbCBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7SmF2YVNjcmlwdEZ1bmN0aW9uU2lnbmF0dXJlfSBzaWduYXR1cmUgLSBDb252ZXJ0ZWQgc2lnbmF0dXJlLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBKYXZhU2NyaXB0RnVuY3Rpb25TaWduYXR1cmU+fSBmdW5jdGlvbnMgLSBNb2R1bGUgc2lnbmF0dXJlcy5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gdmFsdWVSZWNvcmROYW1lcyAtIE5vbWluYWwgZGVjbGFyYXRpb25zIGF2YWlsYWJsZSBpbiB2YWx1ZSBwb3NpdGlvbnMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPn0gcmVjb3JkcyAtIFJlY29yZCBkZWNsYXJhdGlvbnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBjbGFzc2VzIC0gUmVmZXJlbmNlIGNsYXNzZXMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvck5hbWVzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IHNvdXJjZSBuYW1lLlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPn0gZXJyb3JzIC0gRXJyb3IgZGVjbGFyYXRpb25zIGJ5IGlkZW50aXR5LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBnZW5lcmF0ZWQgc2NhbGFyIG91dHB1dCBtYXkgY29udGFpbiBzaWduZWQgemVyby5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEZ1bmN0aW9uKG5vZGUsIHNpZ25hdHVyZSwgZnVuY3Rpb25zLCByZWNvcmROYW1lcywgdmFsdWVSZWNvcmROYW1lcywgcmVjb3JkcywgY2xhc3NlcywgZXJyb3JOYW1lcywgZXJyb3JzLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkKSB7XG4gIGNvbnN0IGNvbnRleHQgPSB7XG4gICAgYmluZGluZ3M6IG5ldyBNYXAoc2lnbmF0dXJlLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyLnR5cGVdKSksXG4gICAgY2xhc3NlcyxcbiAgICBlcnJvck5hbWVzLFxuICAgIGVycm9ycyxcbiAgICBmdW5jdGlvbnMsXG4gICAgb3JkZXJlZE1hcERlY2xhcmF0aW9uczogb3JkZXJlZE1hcERlY2xhcmF0aW9uc0Zvcihub2RlLmJvZHkpLFxuICAgIHJlY29yZE5hbWVzLFxuICAgIHJlY29yZHMsXG4gICAgcmV0dXJuVHlwZTogc2lnbmF0dXJlLnJldHVyblR5cGUsXG4gICAgdHlwZVBhcmFtZXRlcnM6IG5ldyBNYXAoKHNpZ25hdHVyZS50eXBlUGFyYW1ldGVycyA/PyBbXSkubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyXSkpLFxuICAgIHZhbHVlUmVjb3JkTmFtZXNcbiAgfVxuICBjb25zdCBib2R5ID0gY29udmVydEJsb2NrKG5vZGUuYm9keSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dClcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keSxcbiAgICBraW5kOiBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIixcbiAgICBsb2NhdGlvbjogc2lnbmF0dXJlLmxvY2F0aW9uLFxuICAgIG5hbWU6IHNpZ25hdHVyZS5uYW1lLFxuICAgIHBhcmFtZXRlcnM6IHNpZ25hdHVyZS5wYXJhbWV0ZXJzLFxuICAgIHJldHVyblR5cGU6IHNpZ25hdHVyZS5yZXR1cm5UeXBlLFxuICAgIC4uLihzaWduYXR1cmUudHlwZVBhcmFtZXRlcnMgPyB7dHlwZVBhcmFtZXRlcnM6IHNpZ25hdHVyZS50eXBlUGFyYW1ldGVyc30gOiB7fSlcbiAgfSwge25hbWU6IHNpZ25hdHVyZS5uYW1lTG9jYXRpb259KVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHBhcnNlci1vd25lZCBwYWlyIGxvb3BzIHRvIGV4YWN0IGRlY2xhcmF0aW9ucyBpbnNpZGUgb25lIGxleGljYWwgb3duZXIuXG4gKiBBbWJpZ3VvdXMgc2FtZS1uYW1lIGRlY2xhcmF0aW9ucyBwcm9kdWNlIG5vIGV2aWRlbmNlIGFuZCBmYWlsIGR1cmluZyBsb29wIGNvbnZlcnNpb24uXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gRnVuY3Rpb24gYm9keSBvciBlbnRyeS1wb2ludCBzdWJ0cmVlLlxuICogQHJldHVybnMge1NldDxvYmplY3Q+fSBFeGFjdCBwYWlyLWl0ZXJhdGVkIHBhcnNlciBkZWNsYXJhdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIG9yZGVyZWRNYXBEZWNsYXJhdGlvbnNGb3IodmFsdWUpIHtcbiAgLyoqIEB0eXBlIHt7ZGVjbGFyYXRpb246IG9iamVjdCwgbmFtZTogc3RyaW5nLCBvZmZzZXQ6IG51bWJlcn1bXX0gKi9cbiAgY29uc3QgZGVjbGFyYXRpb25zID0gW11cbiAgLyoqIEB0eXBlIHt7bmFtZTogc3RyaW5nLCBvZmZzZXQ6IG51bWJlcn1bXX0gKi9cbiAgY29uc3QgcmVjZWl2ZXJzID0gW11cbiAgY29uc3Qgc2VlbiA9IG5ldyBXZWFrU2V0KClcbiAgLyoqXG4gICAqIFZpc2l0cyBvbmUgcGFyc2VyIGNhbmRpZGF0ZS5cbiAgICogQHBhcmFtIHt1bmtub3dufSBjYW5kaWRhdGUgLSBQYXJzZXIgY2FuZGlkYXRlLlxuICAgKi9cbiAgY29uc3QgdmlzaXQgPSAoY2FuZGlkYXRlKSA9PiB7XG4gICAgaWYgKCFjYW5kaWRhdGUgfHwgdHlwZW9mIGNhbmRpZGF0ZSAhPSBcIm9iamVjdFwiIHx8IHNlZW4uaGFzKGNhbmRpZGF0ZSkpIHJldHVyblxuICAgIHNlZW4uYWRkKGNhbmRpZGF0ZSlcbiAgICBjb25zdCB0eXBlID0gUmVmbGVjdC5nZXQoY2FuZGlkYXRlLCBcInR5cGVcIilcblxuICAgIGlmICh0eXBlID09IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiIHx8IHR5cGUgPT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIpIHJldHVyblxuICAgIGlmICh0eXBlID09IFwiVmFyaWFibGVEZWNsYXJhdG9yXCIpIHtcbiAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwiaWRcIilcblxuICAgICAgaWYgKFJlZmxlY3QuZ2V0KGlkZW50aWZpZXIsIFwidHlwZVwiKSA9PSBcIklkZW50aWZpZXJcIikgZGVjbGFyYXRpb25zLnB1c2goe1xuICAgICAgICBkZWNsYXJhdGlvbjogY2FuZGlkYXRlLFxuICAgICAgICBuYW1lOiBSZWZsZWN0LmdldChpZGVudGlmaWVyLCBcIm5hbWVcIiksXG4gICAgICAgIG9mZnNldDogUmVmbGVjdC5nZXQoY2FuZGlkYXRlLCBcInN0YXJ0XCIpXG4gICAgICB9KVxuICAgIH0gZWxzZSBpZiAodHlwZSA9PSBcIkZvck9mU3RhdGVtZW50XCIpIHtcbiAgICAgIGNvbnN0IGxlZnQgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwibGVmdFwiKVxuICAgICAgY29uc3QgcmlnaHQgPSBSZWZsZWN0LmdldChjYW5kaWRhdGUsIFwicmlnaHRcIilcbiAgICAgIGNvbnN0IGxvb3BEZWNsYXJhdGlvbnMgPSBsZWZ0ICYmIHR5cGVvZiBsZWZ0ID09IFwib2JqZWN0XCIgPyBSZWZsZWN0LmdldChsZWZ0LCBcImRlY2xhcmF0aW9uc1wiKSA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgcGF0dGVybiA9IEFycmF5LmlzQXJyYXkobG9vcERlY2xhcmF0aW9ucykgJiYgbG9vcERlY2xhcmF0aW9ucy5sZW5ndGggPT0gMSA/IFJlZmxlY3QuZ2V0KGxvb3BEZWNsYXJhdGlvbnNbMF0sIFwiaWRcIikgOiB1bmRlZmluZWRcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gcGF0dGVybiAmJiB0eXBlb2YgcGF0dGVybiA9PSBcIm9iamVjdFwiID8gUmVmbGVjdC5nZXQocGF0dGVybiwgXCJlbGVtZW50c1wiKSA6IHVuZGVmaW5lZFxuXG4gICAgICBpZiAoUmVmbGVjdC5nZXQobGVmdCwgXCJraW5kXCIpID09IFwiY29uc3RcIiAmJiBSZWZsZWN0LmdldChwYXR0ZXJuLCBcInR5cGVcIikgPT0gXCJBcnJheVBhdHRlcm5cIiAmJlxuICAgICAgICBBcnJheS5pc0FycmF5KGVsZW1lbnRzKSAmJiBlbGVtZW50cy5sZW5ndGggPT0gMiAmJiBlbGVtZW50cy5ldmVyeSgoZWxlbWVudCkgPT4gUmVmbGVjdC5nZXQoZWxlbWVudCwgXCJ0eXBlXCIpID09IFwiSWRlbnRpZmllclwiKSAmJlxuICAgICAgICBSZWZsZWN0LmdldChyaWdodCwgXCJ0eXBlXCIpID09IFwiSWRlbnRpZmllclwiKSByZWNlaXZlcnMucHVzaCh7XG4gICAgICAgIG5hbWU6IFJlZmxlY3QuZ2V0KHJpZ2h0LCBcIm5hbWVcIiksXG4gICAgICAgIG9mZnNldDogUmVmbGVjdC5nZXQoY2FuZGlkYXRlLCBcInN0YXJ0XCIpXG4gICAgICB9KVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IFtrZXksIGNoaWxkXSBvZiBPYmplY3QuZW50cmllcyhjYW5kaWRhdGUpKSB7XG4gICAgICBpZiAoW1wiZXh0cmFcIiwgXCJpbm5lckNvbW1lbnRzXCIsIFwibGVhZGluZ0NvbW1lbnRzXCIsIFwibG9jXCIsIFwidHJhaWxpbmdDb21tZW50c1wiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSB7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBjaGlsZCkgdmlzaXQoaXRlbSlcbiAgICAgIH0gZWxzZSB2aXNpdChjaGlsZClcbiAgICB9XG4gIH1cblxuICB2aXNpdCh2YWx1ZSlcbiAgY29uc3Qgc2VsZWN0ZWQgPSBuZXcgU2V0KClcbiAgZm9yIChjb25zdCByZWNlaXZlciBvZiByZWNlaXZlcnMpIHtcbiAgICBjb25zdCBtYXRjaGVzID0gZGVjbGFyYXRpb25zLmZpbHRlcigoe25hbWUsIG9mZnNldH0pID0+IG5hbWUgPT0gcmVjZWl2ZXIubmFtZSAmJiBvZmZzZXQgPCByZWNlaXZlci5vZmZzZXQpXG5cbiAgICBpZiAobWF0Y2hlcy5sZW5ndGggPT0gMSkgc2VsZWN0ZWQuYWRkKG1hdGNoZXNbMF0uZGVjbGFyYXRpb24pXG4gIH1cblxuICByZXR1cm4gc2VsZWN0ZWRcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhhY3QgZW1wdHkgbmF0aXZlIEVycm9yIHN1YmNsYXNzLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gbm9kZSAtIEJhYmVsIGNsYXNzIGRlY2xhcmF0aW9uLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFByZWRlY2xhcmVkIHNlbWFudGljIGVycm9yLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9ufSBTZW1hbnRpYyBlcnJvciBkZWNsYXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEphdmFTY3JpcHRFcnJvcihub2RlLCBkZWNsYXJhdGlvbiwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAoIW5vZGUuaWQgfHwgbm9kZS5zdXBlckNsYXNzPy50eXBlICE9IFwiSWRlbnRpZmllclwiIHx8IG5vZGUuc3VwZXJDbGFzcy5uYW1lICE9IFwiRXJyb3JcIiB8fFxuICAgIG5vZGUuYm9keS5ib2R5Lmxlbmd0aCAhPSAwIHx8IG5vZGUuZGVjb3JhdG9ycz8ubGVuZ3RoIHx8IG5vZGUudHlwZVBhcmFtZXRlcnMgfHwgbm9kZS5zdXBlclR5cGVQYXJhbWV0ZXJzIHx8XG4gICAgUmVmbGVjdC5nZXQobm9kZSwgXCJhYnN0cmFjdFwiKSB8fCBSZWZsZWN0LmdldChub2RlLCBcImRlY2xhcmVcIikgfHwgUmVmbGVjdC5nZXQobm9kZSwgXCJpbXBsZW1lbnRzXCIpPy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibm9uY2Fub25pY2FsIHR5cGVkIGVycm9yIGRlY2xhcmF0aW9uXCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoZGVjbGFyYXRpb24sIHtcbiAgICBuYW1lOiBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5pZCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgdHlwZTogaWRlbnRpZmllckxvY2F0aW9uKG5vZGUuc3VwZXJDbGFzcywgZmlsZW5hbWUsIHNvdXJjZSlcbiAgfSlcbn1cblxuLyoqXG4gKiBQcmVkZWNsYXJlcyB0aGUgYm91bmRlZCBuYXRpdmUgcHJpdmF0ZS1maWVsZCByZWZlcmVuY2UtY2xhc3MgcHJvZmlsZSBhbmQgYWxsIGNhbGxhYmxlIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBub2RlIC0gUGFyc2VyIGNsYXNzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFByZWRlY2xhcmVkIGNsYXNzIGlkZW50aXR5LlxuICogQHBhcmFtIHtNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FZmZlY3RSZXNvdXJjZURlY2xhcmF0aW9uPn0gbm9taW5hbE5hbWVzIC0gTm9taW5hbCB0eXBlcyBieSBuYW1lLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gU2VtYW50aWMgY2xhc3MuXG4gKi9cbmZ1bmN0aW9uIHByZWRlY2xhcmVSZWZlcmVuY2VDbGFzcyhub2RlLCBkZWNsYXJhdGlvbiwgbm9taW5hbE5hbWVzLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmICghbm9kZS5pZCB8fCBub2RlLnN1cGVyQ2xhc3MgfHwgbm9kZS5kZWNvcmF0b3JzPy5sZW5ndGggfHwgbm9kZS50eXBlUGFyYW1ldGVycyB8fCBub2RlLnN1cGVyVHlwZVBhcmFtZXRlcnMgfHxcbiAgICBSZWZsZWN0LmdldChub2RlLCBcImFic3RyYWN0XCIpIHx8IFJlZmxlY3QuZ2V0KG5vZGUsIFwiZGVjbGFyZVwiKSB8fCBSZWZsZWN0LmdldChub2RlLCBcImltcGxlbWVudHNcIik/Lmxlbmd0aCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJyZWZlcmVuY2UgY2xhc3MgaW5oZXJpdGFuY2UsIGdlbmVyaWNzLCBkZWNvcmF0aW9uLCBvciBtb2RpZmllclwiLCBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBjb25zdHJ1Y3Rvck5vZGVzID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ2xhc3NNZXRob2RbXX0gKi8gKFxuICAgIG5vZGUuYm9keS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIudHlwZSA9PSBcIkNsYXNzTWV0aG9kXCIgJiYgbWVtYmVyLmtpbmQgPT0gXCJjb25zdHJ1Y3RvclwiKSlcbiAgY29uc3QgZmllbGROb2RlcyA9IG5vZGUuYm9keS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIudHlwZSA9PSBcIkNsYXNzUHJvcGVydHlcIiB8fCBtZW1iZXIudHlwZSA9PSBcIkNsYXNzUHJpdmF0ZVByb3BlcnR5XCIpXG4gIGNvbnN0IG1ldGhvZE5vZGVzID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ2xhc3NNZXRob2RbXX0gKi8gKFxuICAgIG5vZGUuYm9keS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIudHlwZSA9PSBcIkNsYXNzTWV0aG9kXCIgJiYgbWVtYmVyLmtpbmQgPT0gXCJtZXRob2RcIikpXG5cbiAgaWYgKGNvbnN0cnVjdG9yTm9kZXMubGVuZ3RoICE9IDEgfHwgZmllbGROb2Rlcy5sZW5ndGggPT0gMCB8fFxuICAgIGZpZWxkTm9kZXMubGVuZ3RoICsgbWV0aG9kTm9kZXMubGVuZ3RoICsgY29uc3RydWN0b3JOb2Rlcy5sZW5ndGggIT0gbm9kZS5ib2R5LmJvZHkubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcInJlZmVyZW5jZSBjbGFzcyByZXF1aXJlcyBwcml2YXRlIGZpZWxkcywgb25lIGNvbnN0cnVjdG9yLCBhbmQgb3JkaW5hcnkgbWV0aG9kc1wiLCBsb2NhdGlvbilcbiAgfVxuICBkZWNsYXJhdGlvbi5maWVsZHMgPSBmaWVsZE5vZGVzLm1hcCgobWVtYmVyLCBpbmRleCkgPT4ge1xuICAgIGNvbnN0IGZpZWxkTG9jYXRpb24gPSBub2RlTG9jYXRpb24obWVtYmVyLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGxldCBuYW1lXG4gICAgbGV0IG5hbWVMb2NhdGlvblxuICAgIGxldCB0eXBlXG5cbiAgICBpZiAobGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIpIHtcbiAgICAgIGlmIChtZW1iZXIudHlwZSAhPSBcIkNsYXNzUHJvcGVydHlcIiB8fCBtZW1iZXIua2V5LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgbWVtYmVyLmNvbXB1dGVkIHx8IG1lbWJlci5zdGF0aWMgfHxcbiAgICAgICAgbWVtYmVyLmFjY2Vzc2liaWxpdHkgIT0gXCJwcml2YXRlXCIgfHwgbWVtYmVyLnJlYWRvbmx5IHx8IG1lbWJlci52YWx1ZSB8fCBtZW1iZXIub3B0aW9uYWwgfHwgbWVtYmVyLmRlY29yYXRvcnM/Lmxlbmd0aCB8fFxuICAgICAgICBSZWZsZWN0LmdldChtZW1iZXIsIFwiYWJzdHJhY3RcIikgfHwgUmVmbGVjdC5nZXQobWVtYmVyLCBcImRlY2xhcmVcIikpIHtcbiAgICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcIm5vbmNhbm9uaWNhbCBwcml2YXRlIGluc3RhbmNlIGZpZWxkXCIsIGZpZWxkTG9jYXRpb24pXG4gICAgICB9XG4gICAgICBuYW1lID0gbWVtYmVyLmtleS5uYW1lXG4gICAgICBuYW1lTG9jYXRpb24gPSBpZGVudGlmaWVyTG9jYXRpb24obWVtYmVyLmtleSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIHR5cGUgPSBjb252ZXJ0VHlwZVNjcmlwdFR5cGUobWVtYmVyLnR5cGVBbm5vdGF0aW9uLCBgUHJpdmF0ZSBmaWVsZCAnJHtuYW1lfSdgLCBmaWVsZExvY2F0aW9uLCBmaWxlbmFtZSwgc291cmNlLCBub21pbmFsTmFtZXMpXG4gICAgfSBlbHNlIHtcbiAgICAgIGlmIChtZW1iZXIudHlwZSAhPSBcIkNsYXNzUHJpdmF0ZVByb3BlcnR5XCIgfHwgbWVtYmVyLmtleS50eXBlICE9IFwiUHJpdmF0ZU5hbWVcIiB8fCBtZW1iZXIuc3RhdGljIHx8IG1lbWJlci52YWx1ZSB8fFxuICAgICAgICBtZW1iZXIuZGVjb3JhdG9ycz8ubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJub25jYW5vbmljYWwgcHJpdmF0ZSBpbnN0YW5jZSBmaWVsZFwiLCBmaWVsZExvY2F0aW9uKVxuICAgICAgfVxuICAgICAgbmFtZSA9IG1lbWJlci5rZXkuaWQubmFtZVxuICAgICAgbmFtZUxvY2F0aW9uID0gaWRlbnRpZmllckxvY2F0aW9uKG1lbWJlci5rZXkuaWQsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgICBjb25zdCBjb21tZW50ID0gbWVtYmVyLmxlYWRpbmdDb21tZW50cz8uYXQoLTEpXG4gICAgICBjb25zdCBnYXAgPSBjb21tZW50ID8gc291cmNlLnNsaWNlKGNvbW1lbnQuZW5kID8/IDAsIG1lbWJlci5zdGFydCA/PyAwKSA6IFwiXCJcbiAgICAgIGNvbnN0IGJsb2NrID0gY29tbWVudD8udHlwZSA9PSBcIkNvbW1lbnRCbG9ja1wiICYmIGNvbW1lbnQudmFsdWUuc3RhcnRzV2l0aChcIipcIikgJiYgL15cXHMqJC91LnRlc3QoZ2FwKVxuICAgICAgICA/IHBhcnNlQ29tbWVudChgLyoke2NvbW1lbnQudmFsdWV9Ki9gKVswXSA6IHVuZGVmaW5lZFxuICAgICAgY29uc3QgdGFncyA9IGJsb2NrPy50YWdzLmZpbHRlcigodGFnKSA9PiB0YWcudGFnID09IFwidHlwZVwiKSA/PyBbXVxuXG4gICAgICBpZiAoIWNvbW1lbnQgfHwgdGFncy5sZW5ndGggIT0gMSB8fCB0YWdzWzBdLm5hbWUgfHwgdGFnc1swXS5kZXNjcmlwdGlvbikge1xuICAgICAgICByZXR1cm4gbWlzc2luZ1R5cGUobGFuZ3VhZ2UsIGBQcml2YXRlIGZpZWxkICcke25hbWV9J2AsIGZpZWxkTG9jYXRpb24pXG4gICAgICB9XG4gICAgICB0eXBlID0gY29udmVydFR5cGUodGFnc1swXS50eXBlLCBsYW5ndWFnZSwgYFByaXZhdGUgZmllbGQgJyR7bmFtZX0nYCwgZmllbGRMb2NhdGlvbiwgc291cmNlLFxuICAgICAgICBjb21tZW50VGFnTG9jYXRpb24oLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ29tbWVudEJsb2NrfSAqLyAoY29tbWVudCksIHRhZ3NbMF0sIFwidHlwZVwiLCBmaWxlbmFtZSwgc291cmNlKSwgbm9taW5hbE5hbWVzKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtpZDogYCR7ZGVjbGFyYXRpb24uaWR9OmZpZWxkOiR7aW5kZXh9YCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUHJpdmF0ZUZpZWxkXCIpLFxuICAgICAgbG9jYXRpb246IGZpZWxkTG9jYXRpb24sIG5hbWUsIHR5cGV9LCB7bmFtZTogbmFtZUxvY2F0aW9ufSlcbiAgfSlcbiAgY29uc3Qgb3duZWRGaWVsZHMgPSBkZWNsYXJhdGlvbi5maWVsZHMuZmlsdGVyKCh7dHlwZX0pID0+IHR5cGUua2luZCA9PSBcIk93bmVkUmVzb3VyY2VUeXBlXCIpXG5cbiAgaWYgKG93bmVkRmllbGRzLmxlbmd0aCA9PSAxKSB7XG4gICAgY29uc3Qgb3duZWRGaWVsZCA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUHJpdmF0ZUZpZWxkICYge3R5cGU6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLk93bmVkUmVzb3VyY2VUeXBlfX0gKi8gKG93bmVkRmllbGRzWzBdKVxuXG4gICAgZGVjbGFyYXRpb24ub3duZXJzaGlwID0ge2ZpZWxkSWQ6IC8qKiBAdHlwZSB7c3RyaW5nfSAqLyAob3duZWRGaWVsZC5pZCksIGtpbmQ6IFwib3duZWRSZXNvdXJjZVwiLCByZXNvdXJjZUlkOiBvd25lZEZpZWxkLnR5cGUucmVzb3VyY2VJZH1cbiAgfVxuXG4gIGNvbnN0IGNvbnN0cnVjdG9yTm9kZSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkNsYXNzTWV0aG9kfSAqLyAoY29uc3RydWN0b3JOb2Rlc1swXSlcbiAgY29uc3QgY29uc3RydWN0b3JTaWduYXR1cmUgPSBjb252ZXJ0Q2xhc3NDYWxsYWJsZVNpZ25hdHVyZShjb25zdHJ1Y3Rvck5vZGUsIGRlY2xhcmF0aW9uLCBub21pbmFsTmFtZXMsIGxhbmd1YWdlLFxuICAgIGZpbGVuYW1lLCBzb3VyY2UsIHRydWUpXG4gIGRlY2xhcmF0aW9uLmNvbnN0cnVjdG9yID0gd2l0aFBhcnNlclJhbmdlcyh7Ym9keTogLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gKi8gKHt9KSxcbiAgICBpZDogYCR7ZGVjbGFyYXRpb24uaWR9OmNvbnN0cnVjdG9yYCwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQ29uc3RydWN0b3JEZWNsYXJhdGlvblwiKSwgbG9jYXRpb246IGNvbnN0cnVjdG9yU2lnbmF0dXJlLmxvY2F0aW9uLFxuICAgIHBhcmFtZXRlcnM6IGNvbnN0cnVjdG9yU2lnbmF0dXJlLnBhcmFtZXRlcnN9LCB7Y29uc3RydWN0b3I6IGNvbnN0cnVjdG9yU2lnbmF0dXJlLm5hbWVMb2NhdGlvbn0pXG4gIGRlY2xhcmF0aW9uLm1ldGhvZHMgPSBtZXRob2ROb2Rlcy5tYXAoKG1ldGhvZE5vZGUsIGluZGV4KSA9PiB7XG4gICAgY29uc3Qgc2lnbmF0dXJlID0gY29udmVydENsYXNzQ2FsbGFibGVTaWduYXR1cmUobWV0aG9kTm9kZSwgZGVjbGFyYXRpb24sIG5vbWluYWxOYW1lcywgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGZhbHNlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2JvZHk6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9ICovICh7fSksIGlkOiBgJHtkZWNsYXJhdGlvbi5pZH06bWV0aG9kOiR7aW5kZXh9YCxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIk1ldGhvZERlY2xhcmF0aW9uXCIpLCBsb2NhdGlvbjogc2lnbmF0dXJlLmxvY2F0aW9uLCBuYW1lOiBzaWduYXR1cmUubmFtZSxcbiAgICAgIHBhcmFtZXRlcnM6IHNpZ25hdHVyZS5wYXJhbWV0ZXJzLCByZXR1cm5UeXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSAqLyAoc2lnbmF0dXJlLnJldHVyblR5cGUpfSxcbiAgICB7bmFtZTogc2lnbmF0dXJlLm5hbWVMb2NhdGlvbn0pXG4gIH0pXG5cbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoZGVjbGFyYXRpb24sIHtuYW1lOiBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5pZCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSByZWZlcmVuY2UgY2xhc3MgYm9keSBhZnRlciBldmVyeSBjbGFzcyBzaWduYXR1cmUgaXMgY29tcGxldGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBub2RlIC0gUGFyc2VyIGNsYXNzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIENvbXBsZXRlIHByZWRlY2xhcmVkIGNsYXNzIHNpZ25hdHVyZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IG5vbWluYWxOYW1lcyAtIE5vbWluYWwgdHlwZXMgYnkgbmFtZS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gdmFsdWVOYW1lcyAtIE5vbWluYWwgY29uc3RydWN0b3JzIGJ5IG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uPn0gcmVjb3JkcyAtIFJlY29yZHMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNsYXNzRGVjbGFyYXRpb24+fSBjbGFzc2VzIC0gQ2xhc3NlcyBieSBpZGVudGl0eS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgSmF2YVNjcmlwdEZ1bmN0aW9uU2lnbmF0dXJlPn0gZnVuY3Rpb25zIC0gVG9wLWxldmVsIHNpZ25hdHVyZXMuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvck5hbWVzIC0gRXJyb3JzIGJ5IG5hbWUuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb24+fSBlcnJvcnMgLSBFcnJvcnMgYnkgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBzY2FsYXIgb3V0cHV0IGNhbm9uaWNhbGl6ZXMgemVyby5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBDb21wbGV0ZWQgc2VtYW50aWMgY2xhc3MuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRSZWZlcmVuY2VDbGFzc0JvZGllcyhub2RlLCBkZWNsYXJhdGlvbiwgbm9taW5hbE5hbWVzLCB2YWx1ZU5hbWVzLCByZWNvcmRzLCBjbGFzc2VzLCBmdW5jdGlvbnMsIGVycm9yTmFtZXMsXG4gIGVycm9ycywgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCkge1xuICBjb25zdCBjb25zdHJ1Y3Rvck5vZGUgPSAvKiogQHR5cGUge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5DbGFzc01ldGhvZH0gKi8gKFxuICAgIG5vZGUuYm9keS5ib2R5LmZpbmQoKG1lbWJlcikgPT4gbWVtYmVyLnR5cGUgPT0gXCJDbGFzc01ldGhvZFwiICYmIG1lbWJlci5raW5kID09IFwiY29uc3RydWN0b3JcIikpXG4gIGNvbnN0IG1ldGhvZE5vZGVzID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ2xhc3NNZXRob2RbXX0gKi8gKFxuICAgIG5vZGUuYm9keS5ib2R5LmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIudHlwZSA9PSBcIkNsYXNzTWV0aG9kXCIgJiYgbWVtYmVyLmtpbmQgPT0gXCJtZXRob2RcIikpXG4gIGNvbnN0IGJhc2VDb250ZXh0ID0ge2JpbmRpbmdzOiBuZXcgTWFwKCksIGNsYXNzZXMsIGN1cnJlbnRDbGFzczogZGVjbGFyYXRpb24sIGVycm9yTmFtZXMsIGVycm9ycywgZnVuY3Rpb25zLFxuICAgIHJlY29yZE5hbWVzOiBub21pbmFsTmFtZXMsIHJlY29yZHMsIHZhbHVlUmVjb3JkTmFtZXM6IHZhbHVlTmFtZXN9XG4gIGNvbnN0IGNvbnN0cnVjdG9yQ29udGV4dCA9IHsuLi5iYXNlQ29udGV4dCxcbiAgICBiaW5kaW5nczogbmV3IE1hcChkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5wYXJhbWV0ZXJzLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlci50eXBlXSkpLFxuICAgIHJldHVyblR5cGU6IHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJUeXBlUmVmZXJlbmNlXCIpLCBuYW1lOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJ2b2lkXCIpfX1cblxuICBkZWNsYXJhdGlvbi5jb25zdHJ1Y3Rvci5ib2R5ID0gY29udmVydEJsb2NrKGNvbnN0cnVjdG9yTm9kZS5ib2R5LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLFxuICAgIGNvbnN0cnVjdG9yQ29udGV4dClcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IG1ldGhvZE5vZGVzLmxlbmd0aDsgaW5kZXggKz0gMSkge1xuICAgIGNvbnN0IG1ldGhvZCA9IGRlY2xhcmF0aW9uLm1ldGhvZHNbaW5kZXhdXG4gICAgY29uc3QgY29udGV4dCA9IHsuLi5iYXNlQ29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAobWV0aG9kLnBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyLnR5cGVdKSksXG4gICAgICByZXR1cm5UeXBlOiBtZXRob2QucmV0dXJuVHlwZX1cblxuICAgIG1ldGhvZC5ib2R5ID0gY29udmVydEJsb2NrKG1ldGhvZE5vZGVzW2luZGV4XS5ib2R5LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjb250ZXh0KVxuICB9XG5cbiAgcmV0dXJuIGRlY2xhcmF0aW9uXG59XG5cbi8qKlxuICogUmVhZHMgb25lIGNvbnN0cnVjdG9yIG9yIG1ldGhvZCBzaWduYXR1cmUgd2l0aG91dCBhZG1pdHRpbmcgb3ZlcmxvYWRzIG9yIG1vZGlmaWVycy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkNsYXNzTWV0aG9kfSBub2RlIC0gUGFyc2VyIG1ldGhvZC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbn0gZGVjbGFyYXRpb24gLSBEZWNsYXJpbmcgY2xhc3MuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSBub21pbmFsTmFtZXMgLSBOb21pbmFsIHR5cGVzLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IGNvbnN0cnVjdG9yIC0gV2hldGhlciB0aGlzIGlzIHRoZSBjb25zdHJ1Y3Rvci5cbiAqIEByZXR1cm5zIHt7bG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBuYW1lOiBzdHJpbmcsIG5hbWVMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHBhcmFtZXRlcnM6IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdLCByZXR1cm5UeXBlPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU2VtYW50aWNGdW5jdGlvblJldHVyblR5cGV9fSBTaWduYXR1cmUuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRDbGFzc0NhbGxhYmxlU2lnbmF0dXJlKG5vZGUsIGRlY2xhcmF0aW9uLCBub21pbmFsTmFtZXMsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb25zdHJ1Y3Rvcikge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLmNvbXB1dGVkIHx8IG5vZGUuc3RhdGljIHx8IG5vZGUuYXN5bmMgfHwgbm9kZS5nZW5lcmF0b3IgfHwgbm9kZS5kZWNvcmF0b3JzPy5sZW5ndGggfHwgbm9kZS50eXBlUGFyYW1ldGVycyB8fFxuICAgIG5vZGUua2V5LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgY29uc3RydWN0b3IgIT0gKG5vZGUua2luZCA9PSBcImNvbnN0cnVjdG9yXCIpIHx8XG4gICAgbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCIgJiYgbm9kZS5hY2Nlc3NpYmlsaXR5ICE9IG51bGwpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibm9uY2Fub25pY2FsIHJlZmVyZW5jZSBjbGFzcyBjYWxsYWJsZVwiLCBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBkb2N1bWVudGVkID0gbGFuZ3VhZ2UgPT0gXCJqYXZhc2NyaXB0XCJcbiAgICA/IGpzZG9jVHlwZXMoLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKG5vZGUpKSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICA6IHVuZGVmaW5lZFxuICBpZiAoY29uc3RydWN0b3IgJiYgKG5vZGUucmV0dXJuVHlwZSB8fCBkb2N1bWVudGVkPy5yZXR1cm5UeXBlKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJjb25zdHJ1Y3RvciByZXR1cm4gYW5ub3RhdGlvblwiLCBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBwYXJhbWV0ZXJzID0gbm9kZS5wYXJhbXMubWFwKChwYXJhbWV0ZXIpID0+IHtcbiAgICBjb25zdCBwYXJhbWV0ZXJMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAocGFyYW1ldGVyLnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgcGFyYW1ldGVyLm9wdGlvbmFsIHx8IHBhcmFtZXRlci5kZWNvcmF0b3JzPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJub25jYW5vbmljYWwgbWV0aG9kIHBhcmFtZXRlclwiLCBwYXJhbWV0ZXJMb2NhdGlvbilcbiAgICB9XG4gICAgY29uc3QgZG9jdW1lbnRlZFR5cGUgPSBkb2N1bWVudGVkPy5wYXJhbWV0ZXJzLmdldChwYXJhbWV0ZXIubmFtZSlcbiAgICBjb25zdCB0eXBlID0gbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCJcbiAgICAgID8gY29udmVydFR5cGVTY3JpcHRUeXBlKHBhcmFtZXRlci50eXBlQW5ub3RhdGlvbiwgYFBhcmFtZXRlciAnJHtwYXJhbWV0ZXIubmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIG5vbWluYWxOYW1lcylcbiAgICAgIDogY29udmVydFR5cGUoZG9jdW1lbnRlZFR5cGU/LnNvdXJjZVR5cGUsIGxhbmd1YWdlLCBgUGFyYW1ldGVyICcke3BhcmFtZXRlci5uYW1lfSdgLCBwYXJhbWV0ZXJMb2NhdGlvbiwgc291cmNlLFxuICAgICAgICBkb2N1bWVudGVkVHlwZT8ubG9jYXRpb24sIG5vbWluYWxOYW1lcylcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQYXJhbWV0ZXJcIiksIGxvY2F0aW9uOiBwYXJhbWV0ZXJMb2NhdGlvbiwgbmFtZTogcGFyYW1ldGVyLm5hbWUsIHR5cGV9LFxuICAgICAge25hbWU6IGlkZW50aWZpZXJMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfSlcbiAgaWYgKGRvY3VtZW50ZWQgJiYgZG9jdW1lbnRlZC5wYXJhbWV0ZXJzLnNpemUgIT0gcGFyYW1ldGVycy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibWV0aG9kIEpTRG9jIHBhcmFtZXRlciBtaXNtYXRjaFwiLCBsb2NhdGlvbilcbiAgfVxuICBjb25zdCBuYW1lID0gY29uc3RydWN0b3IgPyBcImNvbnN0cnVjdG9yXCIgOiBub2RlLmtleS5uYW1lXG4gIGNvbnN0IG5hbWVMb2NhdGlvbiA9IGlkZW50aWZpZXJMb2NhdGlvbihub2RlLmtleSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAoIWNvbnN0cnVjdG9yICYmIHJlZmVyZW5jZU1ldGhvZEhvb2tzLmhhcyhuYW1lKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgYHJlc2VydmVkIHJlZmVyZW5jZSBtZXRob2QgJyR7bmFtZX0nYCwgbmFtZUxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHtsb2NhdGlvbiwgbmFtZSwgbmFtZUxvY2F0aW9uLCBwYXJhbWV0ZXJzLCAuLi4oY29uc3RydWN0b3IgPyB7fSA6IHtyZXR1cm5UeXBlOiBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIlxuICAgID8gY29udmVydFR5cGVTY3JpcHRSZXR1cm5UeXBlKG5vZGUucmV0dXJuVHlwZSwgYE1ldGhvZCAnJHtuYW1lfScgcmV0dXJuYCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UsIG5vbWluYWxOYW1lcylcbiAgICA6IGNvbnZlcnRSZXR1cm5UeXBlKGRvY3VtZW50ZWQ/LnJldHVyblR5cGU/LnNvdXJjZVR5cGUsIGxhbmd1YWdlLCBgTWV0aG9kICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbiwgc291cmNlLFxuICAgICAgZG9jdW1lbnRlZD8ucmV0dXJuVHlwZT8ubG9jYXRpb24sIG5vbWluYWxOYW1lcyl9KX1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhhY3QgVHlwZVNjcmlwdCByZWFkb25seSBjb25zdHJ1Y3Rvci1wYXJhbWV0ZXIgcmVjb3JkIHByb2ZpbGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5DbGFzc0RlY2xhcmF0aW9ufSBub2RlIC0gQ2xhc3MgZGVjbGFyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9ufSBkZWNsYXJhdGlvbiAtIFByZWRlY2xhcmVkIG5vbWluYWwgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSByZWNvcmROYW1lcyAtIEFsbCBub21pbmFsIGRlY2xhcmF0aW9ucyBieSBuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5SZWNvcmREZWNsYXJhdGlvbn0gU2VtYW50aWMgcmVjb3JkIGRlY2xhcmF0aW9uLlxuICovXG5mdW5jdGlvbiBjb252ZXJ0VHlwZVNjcmlwdFJlY29yZChub2RlLCBkZWNsYXJhdGlvbiwgcmVjb3JkTmFtZXMsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgaW1wbGVtZW50c18gPSBSZWZsZWN0LmdldChub2RlLCBcImltcGxlbWVudHNcIilcbiAgY29uc3QgbWl4aW5zID0gUmVmbGVjdC5nZXQobm9kZSwgXCJtaXhpbnNcIilcblxuICBpZiAoIW5vZGUuaWQpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInR5cGVzY3JpcHRcIiwgXCJhbm9ueW1vdXMgcmVjb3JkIGNsYXNzXCIsIGxvY2F0aW9uKVxuICBpZiAobm9kZS5zdXBlckNsYXNzIHx8IChBcnJheS5pc0FycmF5KGltcGxlbWVudHNfKSAmJiBpbXBsZW1lbnRzXy5sZW5ndGgpIHx8IG5vZGUuZGVjb3JhdG9ycz8ubGVuZ3RoIHx8IG5vZGUuc3VwZXJUeXBlUGFyYW1ldGVycyB8fFxuICAgIFJlZmxlY3QuZ2V0KG5vZGUsIFwiYWJzdHJhY3RcIikgfHwgUmVmbGVjdC5nZXQobm9kZSwgXCJkZWNsYXJlXCIpIHx8IChBcnJheS5pc0FycmF5KG1peGlucykgJiYgbWl4aW5zLmxlbmd0aCkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJ0eXBlc2NyaXB0XCIsIFwicmVjb3JkIGluaGVyaXRhbmNlLCBkZWNvcmF0aW9uLCBvciBtb2RpZmllclwiLCBsb2NhdGlvbilcbiAgfVxuICBpZiAobm9kZS5ib2R5LmJvZHkubGVuZ3RoICE9IDEgfHwgbm9kZS5ib2R5LmJvZHlbMF0udHlwZSAhPSBcIkNsYXNzTWV0aG9kXCIpIHtcbiAgICBjb25zdCBleHRyYSA9IG5vZGUuYm9keS5ib2R5WzFdID8/IG5vZGUuYm9keS5ib2R5WzBdID8/IG5vZGUuYm9keVxuXG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwidHlwZXNjcmlwdFwiLCBcInJlY29yZCBjbGFzcyBib2R5IG91dHNpZGUgb25lIGNvbnN0cnVjdG9yXCIsIG5vZGVMb2NhdGlvbihleHRyYSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgY29uc3RydWN0b3IgPSBub2RlLmJvZHkuYm9keVswXVxuICBjb25zdCB0eXBlUGFyYW1ldGVyTmFtZXMgPSBuZXcgTWFwKChkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/PyBbXSkubWFwKChwYXJhbWV0ZXIpID0+IFtwYXJhbWV0ZXIubmFtZSwgcGFyYW1ldGVyXSkpXG5cbiAgaWYgKGNvbnN0cnVjdG9yLmtpbmQgIT0gXCJjb25zdHJ1Y3RvclwiIHx8IGNvbnN0cnVjdG9yLmNvbXB1dGVkIHx8IGNvbnN0cnVjdG9yLnN0YXRpYyB8fCBjb25zdHJ1Y3Rvci5hc3luYyB8fCBjb25zdHJ1Y3Rvci5nZW5lcmF0b3IgfHxcbiAgICBjb25zdHJ1Y3Rvci5rZXkudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fCBjb25zdHJ1Y3Rvci5rZXkubmFtZSAhPSBcImNvbnN0cnVjdG9yXCIgfHwgY29uc3RydWN0b3IuZGVjb3JhdG9ycz8ubGVuZ3RoIHx8XG4gICAgY29uc3RydWN0b3IucmV0dXJuVHlwZSB8fCBjb25zdHJ1Y3Rvci50eXBlUGFyYW1ldGVycyB8fCBSZWZsZWN0LmdldChjb25zdHJ1Y3RvciwgXCJhY2Nlc3NpYmlsaXR5XCIpIHx8XG4gICAgY29uc3RydWN0b3IuYm9keS5ib2R5Lmxlbmd0aCAhPSAwIHx8IGNvbnN0cnVjdG9yLmJvZHkuZGlyZWN0aXZlcy5sZW5ndGggIT0gMCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInR5cGVzY3JpcHRcIiwgXCJub25jYW5vbmljYWwgcmVjb3JkIGNvbnN0cnVjdG9yXCIsIG5vZGVMb2NhdGlvbihjb25zdHJ1Y3RvciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgZGVjbGFyYXRpb24uZmllbGRzID0gY29uc3RydWN0b3IucGFyYW1zLm1hcCgocGFyYW1ldGVyKSA9PiB7XG4gICAgY29uc3QgZmllbGRMb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAocGFyYW1ldGVyLnR5cGUgIT0gXCJUU1BhcmFtZXRlclByb3BlcnR5XCIgfHwgcGFyYW1ldGVyLnJlYWRvbmx5ICE9PSB0cnVlIHx8IHBhcmFtZXRlci5hY2Nlc3NpYmlsaXR5IHx8IHBhcmFtZXRlci5vdmVycmlkZSB8fFxuICAgICAgcGFyYW1ldGVyLnBhcmFtZXRlci50eXBlICE9IFwiSWRlbnRpZmllclwiIHx8IHBhcmFtZXRlci5wYXJhbWV0ZXIub3B0aW9uYWwgfHwgcGFyYW1ldGVyLnBhcmFtZXRlci5kZWNvcmF0b3JzPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInR5cGVzY3JpcHRcIiwgXCJyZWNvcmQgZmllbGQgb3V0c2lkZSByZWFkb25seSBwYXJhbWV0ZXItcHJvcGVydHkgcHJvZmlsZVwiLCBmaWVsZExvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBpZGVudGlmaWVyID0gcGFyYW1ldGVyLnBhcmFtZXRlclxuICAgIGNvbnN0IGZpZWxkID0ge1xuICAgICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUmVjb3JkRmllbGRcIiksXG4gICAgICBsb2NhdGlvbjogZmllbGRMb2NhdGlvbixcbiAgICAgIG5hbWU6IGlkZW50aWZpZXIubmFtZSxcbiAgICAgIHR5cGU6IGNvbnZlcnRUeXBlU2NyaXB0VHlwZShpZGVudGlmaWVyLnR5cGVBbm5vdGF0aW9uLCBgUmVjb3JkIGZpZWxkICcke2lkZW50aWZpZXIubmFtZX0nYCwgZmllbGRMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSxcbiAgICAgICAgcmVjb3JkTmFtZXMsIHR5cGVQYXJhbWV0ZXJOYW1lcylcbiAgICB9XG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhmaWVsZCwge25hbWU6IGlkZW50aWZpZXJMb2NhdGlvbihpZGVudGlmaWVyLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH0pXG5cbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoZGVjbGFyYXRpb24sIHtuYW1lOiBpZGVudGlmaWVyTG9jYXRpb24obm9kZS5pZCwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBKU0RvYyBjb25zdHJ1Y3Rvci9yZWFkb25seS1hc3NpZ25tZW50L2ZyZWV6ZSByZWNvcmQgcHJvZmlsZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkNsYXNzRGVjbGFyYXRpb259IG5vZGUgLSBDbGFzcyBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb259IGRlY2xhcmF0aW9uIC0gUHJlZGVjbGFyZWQgbm9taW5hbCBpZGVudGl0eS5cbiAqIEBwYXJhbSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0UmVzb3VyY2VEZWNsYXJhdGlvbj59IHJlY29yZE5hbWVzIC0gTm9taW5hbCBkZWNsYXJhdGlvbnMgYnkgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb259IFNlbWFudGljIHJlY29yZCBkZWNsYXJhdGlvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEphdmFTY3JpcHRSZWNvcmQobm9kZSwgZGVjbGFyYXRpb24sIHJlY29yZE5hbWVzLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGltcGxlbWVudHNfID0gUmVmbGVjdC5nZXQobm9kZSwgXCJpbXBsZW1lbnRzXCIpXG4gIGNvbnN0IG1peGlucyA9IFJlZmxlY3QuZ2V0KG5vZGUsIFwibWl4aW5zXCIpXG5cbiAgaWYgKCFub2RlLmlkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJqYXZhc2NyaXB0XCIsIFwiYW5vbnltb3VzIHJlY29yZCBjbGFzc1wiLCBsb2NhdGlvbilcbiAgaWYgKG5vZGUuc3VwZXJDbGFzcyB8fCBub2RlLmRlY29yYXRvcnM/Lmxlbmd0aCB8fCBub2RlLnR5cGVQYXJhbWV0ZXJzIHx8IG5vZGUuc3VwZXJUeXBlUGFyYW1ldGVycyB8fFxuICAgIChBcnJheS5pc0FycmF5KGltcGxlbWVudHNfKSAmJiBpbXBsZW1lbnRzXy5sZW5ndGgpIHx8IChBcnJheS5pc0FycmF5KG1peGlucykgJiYgbWl4aW5zLmxlbmd0aCkpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJqYXZhc2NyaXB0XCIsIFwicmVjb3JkIGluaGVyaXRhbmNlIG9yIGRlY29yYXRpb25cIiwgbG9jYXRpb24pXG4gIH1cbiAgaWYgKG5vZGUuYm9keS5ib2R5Lmxlbmd0aCAhPSAxIHx8IG5vZGUuYm9keS5ib2R5WzBdLnR5cGUgIT0gXCJDbGFzc01ldGhvZFwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiamF2YXNjcmlwdFwiLCBcInJlY29yZCBjbGFzcyBib2R5IG91dHNpZGUgb25lIGNvbnN0cnVjdG9yXCIsIG5vZGVMb2NhdGlvbihub2RlLmJvZHkuYm9keVsxXSA/PyBub2RlLmJvZHkuYm9keVswXSA/PyBub2RlLmJvZHksIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IGNvbnN0cnVjdG9yID0gbm9kZS5ib2R5LmJvZHlbMF1cbiAgY29uc3QgdHlwZVBhcmFtZXRlck5hbWVzID0gbmV3IE1hcCgoZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnMgPz8gW10pLm1hcCgocGFyYW1ldGVyKSA9PiBbcGFyYW1ldGVyLm5hbWUsIHBhcmFtZXRlcl0pKVxuXG4gIGlmIChjb25zdHJ1Y3Rvci5raW5kICE9IFwiY29uc3RydWN0b3JcIiB8fCBjb25zdHJ1Y3Rvci5jb21wdXRlZCB8fCBjb25zdHJ1Y3Rvci5zdGF0aWMgfHwgY29uc3RydWN0b3IuYXN5bmMgfHwgY29uc3RydWN0b3IuZ2VuZXJhdG9yIHx8XG4gICAgY29uc3RydWN0b3Iua2V5LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgY29uc3RydWN0b3Iua2V5Lm5hbWUgIT0gXCJjb25zdHJ1Y3RvclwiIHx8IGNvbnN0cnVjdG9yLmRlY29yYXRvcnM/Lmxlbmd0aCB8fFxuICAgIGNvbnN0cnVjdG9yLnJldHVyblR5cGUgfHwgY29uc3RydWN0b3IudHlwZVBhcmFtZXRlcnMgfHwgY29uc3RydWN0b3IuYm9keS5kaXJlY3RpdmVzLmxlbmd0aCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcImphdmFzY3JpcHRcIiwgXCJub25jYW5vbmljYWwgcmVjb3JkIGNvbnN0cnVjdG9yXCIsIG5vZGVMb2NhdGlvbihjb25zdHJ1Y3RvciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgcGFyYW1ldGVycyA9IGNvbnN0cnVjdG9yLnBhcmFtc1xuXG4gIGlmIChwYXJhbWV0ZXJzLnNvbWUoKHBhcmFtZXRlcikgPT4gcGFyYW1ldGVyLnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgcGFyYW1ldGVyLm9wdGlvbmFsIHx8IHBhcmFtZXRlci5kZWNvcmF0b3JzPy5sZW5ndGgpKSB7XG4gICAgY29uc3QgaW52YWxpZCA9IHBhcmFtZXRlcnMuZmluZCgocGFyYW1ldGVyKSA9PiBwYXJhbWV0ZXIudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fCBwYXJhbWV0ZXIub3B0aW9uYWwgfHwgcGFyYW1ldGVyLmRlY29yYXRvcnM/Lmxlbmd0aClcblxuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcImphdmFzY3JpcHRcIiwgXCJub25jYW5vbmljYWwgcmVjb3JkIGNvbnN0cnVjdG9yIHBhcmFtZXRlclwiLCBub2RlTG9jYXRpb24oaW52YWxpZCA/PyBjb25zdHJ1Y3RvciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgZG9jdW1lbnRlZCA9IGpzZG9jVHlwZXMoLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKGNvbnN0cnVjdG9yKSksIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKGRvY3VtZW50ZWQucmV0dXJuVHlwZSB8fCBkb2N1bWVudGVkLnBhcmFtZXRlcnMuc2l6ZSAhPSBwYXJhbWV0ZXJzLmxlbmd0aCB8fCBjb25zdHJ1Y3Rvci5ib2R5LmJvZHkubGVuZ3RoICE9IHBhcmFtZXRlcnMubGVuZ3RoICsgMSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcImphdmFzY3JpcHRcIiwgXCJpbmNvbXBsZXRlIHJlY29yZCBjb25zdHJ1Y3RvciBwcm9maWxlXCIsIG5vZGVMb2NhdGlvbihjb25zdHJ1Y3RvciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgZGVjbGFyYXRpb24uZmllbGRzID0gcGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlciwgaW5kZXgpID0+IHtcbiAgICBjb25zdCBpZGVudGlmaWVyID0gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuSWRlbnRpZmllcn0gKi8gKHBhcmFtZXRlcilcbiAgICBjb25zdCBzdGF0ZW1lbnQgPSBjb25zdHJ1Y3Rvci5ib2R5LmJvZHlbaW5kZXhdXG4gICAgY29uc3QgZG9jdW1lbnRlZFR5cGUgPSBkb2N1bWVudGVkLnBhcmFtZXRlcnMuZ2V0KGlkZW50aWZpZXIubmFtZSlcblxuICAgIGlmICghZG9jdW1lbnRlZFR5cGUgfHwgc3RhdGVtZW50LnR5cGUgIT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgfHwgc3RhdGVtZW50LmV4cHJlc3Npb24udHlwZSAhPSBcIkFzc2lnbm1lbnRFeHByZXNzaW9uXCIgfHxcbiAgICAgIHN0YXRlbWVudC5leHByZXNzaW9uLm9wZXJhdG9yICE9IFwiPVwiIHx8IHN0YXRlbWVudC5leHByZXNzaW9uLmxlZnQudHlwZSAhPSBcIk1lbWJlckV4cHJlc3Npb25cIiB8fCBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sZWZ0LmNvbXB1dGVkIHx8XG4gICAgICBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sZWZ0Lm9iamVjdC50eXBlICE9IFwiVGhpc0V4cHJlc3Npb25cIiB8fCBzdGF0ZW1lbnQuZXhwcmVzc2lvbi5sZWZ0LnByb3BlcnR5LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHxcbiAgICAgIHN0YXRlbWVudC5leHByZXNzaW9uLmxlZnQucHJvcGVydHkubmFtZSAhPSBpZGVudGlmaWVyLm5hbWUgfHwgc3RhdGVtZW50LmV4cHJlc3Npb24ucmlnaHQudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fFxuICAgICAgc3RhdGVtZW50LmV4cHJlc3Npb24ucmlnaHQubmFtZSAhPSBpZGVudGlmaWVyLm5hbWUpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcImphdmFzY3JpcHRcIiwgXCJyZWNvcmQgZmllbGQgbm90IGluaXRpYWxpemVkIGV4YWN0bHkgb25jZVwiLCBub2RlTG9jYXRpb24oc3RhdGVtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgcmVhZG9ubHlDb21tZW50ID0gc3RhdGVtZW50LmxlYWRpbmdDb21tZW50cz8uYXQoLTEpXG4gICAgY29uc3QgZ2FwID0gcmVhZG9ubHlDb21tZW50ID8gc291cmNlLnNsaWNlKHJlYWRvbmx5Q29tbWVudC5lbmQgPz8gMCwgc3RhdGVtZW50LnN0YXJ0ID8/IDApIDogXCJcIlxuICAgIGNvbnN0IHRhZ3MgPSByZWFkb25seUNvbW1lbnQ/LnR5cGUgPT0gXCJDb21tZW50QmxvY2tcIiAmJiByZWFkb25seUNvbW1lbnQudmFsdWUuc3RhcnRzV2l0aChcIipcIilcbiAgICAgID8gcGFyc2VDb21tZW50KGAvKiR7cmVhZG9ubHlDb21tZW50LnZhbHVlfSovYClbMF0/LnRhZ3MgPz8gW11cbiAgICAgIDogW11cblxuICAgIGlmICghcmVhZG9ubHlDb21tZW50IHx8ICEvXlxccyokL3UudGVzdChnYXApIHx8IHRhZ3MubGVuZ3RoICE9IDEgfHwgdGFnc1swXS50YWcgIT0gXCJyZWFkb25seVwiIHx8XG4gICAgICB0YWdzWzBdLm5hbWUgfHwgdGFnc1swXS50eXBlIHx8IHRhZ3NbMF0uZGVzY3JpcHRpb24pIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcImphdmFzY3JpcHRcIiwgXCJyZWNvcmQgZmllbGQgd2l0aG91dCBleGFjdCBAcmVhZG9ubHkgYW5ub3RhdGlvblwiLCBub2RlTG9jYXRpb24oc3RhdGVtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICB9XG4gICAgY29uc3QgZmllbGQgPSB7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJSZWNvcmRGaWVsZFwiKSxcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24oc3RhdGVtZW50LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIG5hbWU6IGlkZW50aWZpZXIubmFtZSxcbiAgICAgIHR5cGU6IGNvbnZlcnRUeXBlKGRvY3VtZW50ZWRUeXBlLnNvdXJjZVR5cGUsIFwiamF2YXNjcmlwdFwiLCBgUmVjb3JkIGZpZWxkICcke2lkZW50aWZpZXIubmFtZX0nYCxcbiAgICAgICAgbm9kZUxvY2F0aW9uKGlkZW50aWZpZXIsIGZpbGVuYW1lLCBzb3VyY2UpLCBzb3VyY2UsIGRvY3VtZW50ZWRUeXBlLmxvY2F0aW9uLCByZWNvcmROYW1lcywgdHlwZVBhcmFtZXRlck5hbWVzKVxuICAgIH1cblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKGZpZWxkLCB7bmFtZTogaWRlbnRpZmllckxvY2F0aW9uKHN0YXRlbWVudC5leHByZXNzaW9uLmxlZnQucHJvcGVydHksIGZpbGVuYW1lLCBzb3VyY2UpfSlcbiAgfSlcbiAgY29uc3QgZnJlZXplID0gY29uc3RydWN0b3IuYm9keS5ib2R5LmF0KC0xKVxuXG4gIGlmICghZnJlZXplIHx8IGZyZWV6ZS50eXBlICE9IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IGZyZWV6ZS5leHByZXNzaW9uLnR5cGUgIT0gXCJDYWxsRXhwcmVzc2lvblwiIHx8IGZyZWV6ZS5leHByZXNzaW9uLm9wdGlvbmFsIHx8XG4gICAgZnJlZXplLmV4cHJlc3Npb24uYXJndW1lbnRzLmxlbmd0aCAhPSAxIHx8IGZyZWV6ZS5leHByZXNzaW9uLmFyZ3VtZW50c1swXS50eXBlICE9IFwiVGhpc0V4cHJlc3Npb25cIiB8fFxuICAgICFpc0phdmFTY3JpcHRSZWNvcmRGcmVlemUoZnJlZXplLmV4cHJlc3Npb24pKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiamF2YXNjcmlwdFwiLCBcInJlY29yZCBjb25zdHJ1Y3RvciB3aXRob3V0IGZpbmFsIE9iamVjdC5mcmVlemUodGhpcylcIiwgbm9kZUxvY2F0aW9uKGZyZWV6ZSA/PyBjb25zdHJ1Y3RvciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyhkZWNsYXJhdGlvbiwge25hbWU6IGlkZW50aWZpZXJMb2NhdGlvbihub2RlLmlkLCBmaWxlbmFtZSwgc291cmNlKX0pXG59XG5cbi8qKlxuICogUmVjb2duaXplcyB0aGUgY2Fub25pY2FsIHNvdXJjZSBmcmVlemUgb3IgdGhlIGdlbmVyYXRlZCBpZGVudGlmaWVyLWZyZWUgaW50cmluc2ljIG93bmVyLlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuQ2FsbEV4cHJlc3Npb259IGV4cHJlc3Npb24gLSBGaW5hbCBjb25zdHJ1Y3RvciBjYWxsLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIGNhbGwgb3ducyB0aGUgbmF0aXZlIHJlY29yZC1mcmVlemUgb3BlcmF0aW9uLlxuICovXG5mdW5jdGlvbiBpc0phdmFTY3JpcHRSZWNvcmRGcmVlemUoZXhwcmVzc2lvbikge1xuICBjb25zdCBjYWxsZWUgPSBleHByZXNzaW9uLmNhbGxlZVxuXG4gIGlmIChjYWxsZWUudHlwZSAhPSBcIk1lbWJlckV4cHJlc3Npb25cIiB8fCBjYWxsZWUuY29tcHV0ZWQgfHwgY2FsbGVlLm9wdGlvbmFsIHx8XG4gICAgY2FsbGVlLnByb3BlcnR5LnR5cGUgIT0gXCJJZGVudGlmaWVyXCIgfHwgY2FsbGVlLnByb3BlcnR5Lm5hbWUgIT0gXCJmcmVlemVcIikgcmV0dXJuIGZhbHNlXG4gIGlmIChjYWxsZWUub2JqZWN0LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIpIHJldHVybiBjYWxsZWUub2JqZWN0Lm5hbWUgPT0gXCJPYmplY3RcIlxuICBpZiAoY2FsbGVlLm9iamVjdC50eXBlICE9IFwiTWVtYmVyRXhwcmVzc2lvblwiIHx8IGNhbGxlZS5vYmplY3QuY29tcHV0ZWQgfHwgY2FsbGVlLm9iamVjdC5vcHRpb25hbCB8fFxuICAgIGNhbGxlZS5vYmplY3QucHJvcGVydHkudHlwZSAhPSBcIklkZW50aWZpZXJcIiB8fCBjYWxsZWUub2JqZWN0LnByb3BlcnR5Lm5hbWUgIT0gXCJjb25zdHJ1Y3RvclwiKSByZXR1cm4gZmFsc2VcblxuICByZXR1cm4gY2FsbGVlLm9iamVjdC5vYmplY3QudHlwZSA9PSBcIk9iamVjdEV4cHJlc3Npb25cIiAmJiBjYWxsZWUub2JqZWN0Lm9iamVjdC5wcm9wZXJ0aWVzLmxlbmd0aCA9PSAwICYmXG4gICAgY2FsbGVlLm9iamVjdC5vYmplY3QuZXh0cmE/LnBhcmVudGhlc2l6ZWQgPT09IHRydWVcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZXhpc3RpbmcgZXhhY3QgaWYvZWxzZSB0ZXJtaW5hbCBzaGFwZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLklmU3RhdGVtZW50fSBub2RlIC0gQmFiZWwgaWYgc3RhdGVtZW50LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBnZW5lcmF0ZWQgc2NhbGFyIG91dHB1dCBtYXkgY29udGFpbiBzaWduZWQgemVyby5cbiAqIEBwYXJhbSB7SmF2YVNjcmlwdENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgbGV4aWNhbCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuSWZTdGF0ZW1lbnR9IFNlbWFudGljIGJyYW5jaC5cbiAqL1xuZnVuY3Rpb24gY29udmVydElmKG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGNvbnRleHQpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY29uZGl0aW9uID0gY29udmVydEV4cHJlc3Npb24obm9kZS50ZXN0LCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY29udGV4dClcbiAgY29uc3QgY29uc2VxdWVudENvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG4gIGNvbnN0IGFsdGVybmF0ZUNvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG4gIGNvbnN0IGNvbnNlcXVlbnQgPSBub2RlLmNvbnNlcXVlbnQudHlwZSA9PSBcIkJsb2NrU3RhdGVtZW50XCJcbiAgICA/IGNvbnZlcnRCbG9jayhub2RlLmNvbnNlcXVlbnQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGNvbnNlcXVlbnRDb250ZXh0KVxuICAgIDogY29udmVydEJsb2NrKFtub2RlLmNvbnNlcXVlbnRdLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjb25zZXF1ZW50Q29udGV4dCwgbm9kZUxvY2F0aW9uKG5vZGUuY29uc2VxdWVudCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGNvbnN0IGFsdGVybmF0ZSA9IG5vZGUuYWx0ZXJuYXRlXG4gICAgPyBub2RlLmFsdGVybmF0ZS50eXBlID09IFwiQmxvY2tTdGF0ZW1lbnRcIlxuICAgICAgPyBjb252ZXJ0QmxvY2sobm9kZS5hbHRlcm5hdGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGFsdGVybmF0ZUNvbnRleHQpXG4gICAgICA6IGNvbnZlcnRCbG9jayhbbm9kZS5hbHRlcm5hdGVdLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBhbHRlcm5hdGVDb250ZXh0LCBub2RlTG9jYXRpb24obm9kZS5hbHRlcm5hdGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIDogdW5kZWZpbmVkXG5cbiAgcmV0dXJuIHtcbiAgICAuLi4oYWx0ZXJuYXRlID8ge2FsdGVybmF0ZX0gOiB7fSksXG4gICAgY29uZGl0aW9uLFxuICAgIGNvbnNlcXVlbnQsXG4gICAga2luZDogXCJJZlN0YXRlbWVudFwiLFxuICAgIGxvY2F0aW9uXG4gIH1cbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhhY3QgYmxvY2stYm9kaWVkIHByZS1jb25kaXRpb24gbG9vcC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLldoaWxlU3RhdGVtZW50fSBub2RlIC0gQmFiZWwgd2hpbGUgc3RhdGVtZW50LlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gY2Fub25pY2FsWmVyb1JlcXVpcmVkIC0gV2hldGhlciBnZW5lcmF0ZWQgc2NhbGFyIG91dHB1dCBtYXkgY29udGFpbiBzaWduZWQgemVyby5cbiAqIEBwYXJhbSB7SmF2YVNjcmlwdENvbnZlcnNpb25Db250ZXh0fSBjb250ZXh0IC0gVHlwZWQgbGV4aWNhbCBjb252ZXJzaW9uIGNvbnRleHQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuV2hpbGVTdGF0ZW1lbnR9IFNlbWFudGljIGxvb3AuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRXaGlsZShub2RlLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSwgY2Fub25pY2FsWmVyb1JlcXVpcmVkLCBjb250ZXh0KSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUuYm9keS50eXBlICE9IFwiQmxvY2tTdGF0ZW1lbnRcIikge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJ3aGlsZSB3aXRob3V0IGJsb2NrIGJvZHlcIiwgbm9kZUxvY2F0aW9uKG5vZGUuYm9keSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgYm9keUNvbnRleHQgPSB7Li4uY29udGV4dCwgYmluZGluZ3M6IG5ldyBNYXAoY29udGV4dC5iaW5kaW5ncyl9XG5cbiAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGJvZHk6IGNvbnZlcnRCbG9jayhub2RlLmJvZHksIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQsIGJvZHlDb250ZXh0KSxcbiAgICBjb25kaXRpb246IGNvbnZlcnRFeHByZXNzaW9uKG5vZGUudGVzdCwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNvbnRleHQsIHVuZGVmaW5lZCwgdHJ1ZSksXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiV2hpbGVTdGF0ZW1lbnRcIiksXG4gICAgbG9jYXRpb25cbiAgfSwge2tleXdvcmQ6IHRva2VuTG9jYXRpb24obm9kZSwgXCJ3aGlsZVwiLCBub2RlLnN0YXJ0ID8/IDAsIG5vZGUudGVzdC5zdGFydCA/PyBub2RlLmVuZCA/PyBzb3VyY2UubGVuZ3RoLCBmaWxlbmFtZSwgc291cmNlKX0pXG59XG5cbi8qKlxuICogUmVwb3J0cyB3aGV0aGVyIEJhYmVsIHBhcnNlZCBhbiBvcGVyYXRpb24gdGhhdCBtYWtlcyBnZW5lcmF0ZWQgSmF2YVNjcmlwdC1mYW1pbHkgc2NhbGFyIG91dHB1dCByZXF1aXJlIHplcm8gY2Fub25pY2FsaXphdGlvbi5cbiAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBCYWJlbCBwYXJzZXIgc3VidHJlZS5cbiAqIEBwYXJhbSB7V2Vha1NldDxvYmplY3Q+fSBbdmlzaXRlZF0gLSBDeWNsZSBwcm90ZWN0aW9uLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHN1YnRyZWUgY29udGFpbnMgaW50ZWdlciBuZWdhdGlvbiBvciBtdWx0aXBsaWNhdGlvbiBzeW50YXguXG4gKi9cbmZ1bmN0aW9uIHBhcnNlclRyZWVSZXF1aXJlc0Nhbm9uaWNhbFplcm8odmFsdWUsIHZpc2l0ZWQgPSBuZXcgV2Vha1NldCgpKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIpIHJldHVybiBmYWxzZVxuICBpZiAodmlzaXRlZC5oYXModmFsdWUpKSByZXR1cm4gZmFsc2VcblxuICB2aXNpdGVkLmFkZCh2YWx1ZSlcbiAgaWYgKFJlZmxlY3QuZ2V0KHZhbHVlLCBcInR5cGVcIikgPT0gXCJVbmFyeUV4cHJlc3Npb25cIiAmJiBSZWZsZWN0LmdldCh2YWx1ZSwgXCJvcGVyYXRvclwiKSA9PSBcIi1cIikgcmV0dXJuIHRydWVcbiAgaWYgKFJlZmxlY3QuZ2V0KHZhbHVlLCBcInR5cGVcIikgPT0gXCJCaW5hcnlFeHByZXNzaW9uXCIgJiYgUmVmbGVjdC5nZXQodmFsdWUsIFwib3BlcmF0b3JcIikgPT0gXCIqXCIpIHJldHVybiB0cnVlXG5cbiAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHZhbHVlKS5zb21lKChba2V5LCBjaGlsZF0pID0+XG4gICAgIVtcImV4dHJhXCIsIFwiaW5uZXJDb21tZW50c1wiLCBcImxlYWRpbmdDb21tZW50c1wiLCBcImxvY1wiLCBcInRyYWlsaW5nQ29tbWVudHNcIl0uaW5jbHVkZXMoa2V5KSAmJlxuICAgIChBcnJheS5pc0FycmF5KGNoaWxkKVxuICAgICAgPyBjaGlsZC5zb21lKChpdGVtKSA9PiBwYXJzZXJUcmVlUmVxdWlyZXNDYW5vbmljYWxaZXJvKGl0ZW0sIHZpc2l0ZWQpKVxuICAgICAgOiBwYXJzZXJUcmVlUmVxdWlyZXNDYW5vbmljYWxaZXJvKGNoaWxkLCB2aXNpdGVkKSkpXG59XG5cbi8qKlxuICogUmVjb2duaXplcyB0aGUgcGFyc2VyLW93bmVkIHJlY2VpdmVyIHBhcmVudGhlc2VzIGVtaXR0ZWQgb25seSBmb3IgY2Fub25pY2FsIGludGVnZXIgb3V0cHV0LlxuICogQHBhcmFtIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRXhwcmVzc2lvbiB8IGltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdXBlcn0gcmVjZWl2ZXIgLSBRdWFsaWZpZWQtY2FsbCByZWNlaXZlci5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkNhbGxFeHByZXNzaW9ufSBjYWxsIC0gT3V0ZXIgYHRvU3RyaW5nYCBjYWxsLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIHJlY2VpdmVyIGhhcyB0aGUgZ2VuZXJhdGVkIHdyYXBwZXIgc2hhcGUuXG4gKi9cbmZ1bmN0aW9uIGhhc0Nhbm9uaWNhbFplcm9SZWNlaXZlcldyYXBwZXIocmVjZWl2ZXIsIGNhbGwpIHtcbiAgY29uc3QgZXh0cmEgPSBSZWZsZWN0LmdldChyZWNlaXZlciwgXCJleHRyYVwiKVxuICBjb25zdCBleHByZXNzaW9uUGFyZW50aGVzZXMgPSBbXCJCaW5hcnlFeHByZXNzaW9uXCIsIFwiTG9naWNhbEV4cHJlc3Npb25cIiwgXCJVbmFyeUV4cHJlc3Npb25cIl0uaW5jbHVkZXMocmVjZWl2ZXIudHlwZSkgPyAxIDogMFxuICBjb25zdCB3cmFwcGVyUGFyZW50aGVzZXMgPSBleHByZXNzaW9uUGFyZW50aGVzZXMgKyAxXG4gIGNvbnN0IHByb3BlcnR5ID0gY2FsbC5jYWxsZWUudHlwZSA9PSBcIk1lbWJlckV4cHJlc3Npb25cIiA/IGNhbGwuY2FsbGVlLnByb3BlcnR5IDogdW5kZWZpbmVkXG5cbiAgcmV0dXJuIEJvb2xlYW4oZXh0cmEpICYmIHR5cGVvZiBleHRyYSA9PSBcIm9iamVjdFwiICYmIFJlZmxlY3QuZ2V0KGV4dHJhLCBcInBhcmVudGhlc2l6ZWRcIikgPT09IHRydWUgJiZcbiAgICBSZWZsZWN0LmdldChleHRyYSwgXCJwYXJlblN0YXJ0XCIpID09PSBjYWxsLnN0YXJ0ICYmIHR5cGVvZiBjYWxsLnN0YXJ0ID09IFwibnVtYmVyXCIgJiYgdHlwZW9mIGNhbGwuZW5kID09IFwibnVtYmVyXCIgJiZcbiAgICB0eXBlb2YgcmVjZWl2ZXIuc3RhcnQgPT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgcmVjZWl2ZXIuZW5kID09IFwibnVtYmVyXCIgJiYgcHJvcGVydHk/LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiZcbiAgICB0eXBlb2YgcHJvcGVydHkuc3RhcnQgPT0gXCJudW1iZXJcIiAmJiB0eXBlb2YgcHJvcGVydHkuZW5kID09IFwibnVtYmVyXCIgJiYgY2FsbC5jYWxsZWUuc3RhcnQgPT09IGNhbGwuc3RhcnQgJiZcbiAgICByZWNlaXZlci5zdGFydCA9PSBjYWxsLnN0YXJ0ICsgd3JhcHBlclBhcmVudGhlc2VzICYmIHByb3BlcnR5LnN0YXJ0ID09IHJlY2VpdmVyLmVuZCArIHdyYXBwZXJQYXJlbnRoZXNlcyArIDEgJiZcbiAgICBwcm9wZXJ0eS5lbmQgPT0gcHJvcGVydHkuc3RhcnQgKyBcInRvU3RyaW5nXCIubGVuZ3RoICYmIGNhbGwuZW5kID09IHByb3BlcnR5LmVuZCArIDJcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIGNvbnNvbGUubG9nIGVudHJ5LXBvaW50IGNhbGwuXG4gKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdGF0ZW1lbnR9IG5vZGUgLSBCYWJlbCBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHBhcmFtIHtib29sZWFufSBjYW5vbmljYWxaZXJvUmVxdWlyZWQgLSBXaGV0aGVyIHRoaXMgcGFyc2VkIG1vZHVsZSBjb250YWlucyBhIHNpZ24tcHJvZHVjaW5nIGludGVnZXIgb3BlcmF0aW9uLlxuICogQHBhcmFtIHtKYXZhU2NyaXB0Q29udmVyc2lvbkNvbnRleHR9IGNvbnRleHQgLSBUeXBlZCBsZXhpY2FsIGNvbnZlcnNpb24gY29udGV4dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QcmludFN0YXRlbWVudH0gUHJpbnQgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0UHJpbnQobm9kZSwgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UsIGNhbm9uaWNhbFplcm9SZXF1aXJlZCwgY29udGV4dCkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnR5cGUgIT0gXCJFeHByZXNzaW9uU3RhdGVtZW50XCIgfHwgbm9kZS5leHByZXNzaW9uLnR5cGUgIT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBub2RlLnR5cGUsIGxvY2F0aW9uKVxuICB9XG5cbiAgY29uc3QgY2FsbCA9IG5vZGUuZXhwcmVzc2lvblxuICBjb25zdCBjYWxsZWUgPSBjYWxsLmNhbGxlZVxuXG4gIGlmIChjYWxsZWUudHlwZSAhPSBcIk1lbWJlckV4cHJlc3Npb25cIiB8fCBjYWxsZWUuY29tcHV0ZWQgfHwgY2FsbGVlLm9iamVjdC50eXBlICE9IFwiSWRlbnRpZmllclwiIHx8XG4gICAgY2FsbGVlLm9iamVjdC5uYW1lICE9IFwiY29uc29sZVwiIHx8IGNhbGxlZS5wcm9wZXJ0eS50eXBlICE9IFwiSWRlbnRpZmllclwiIHx8IGNhbGxlZS5wcm9wZXJ0eS5uYW1lICE9IFwibG9nXCIgfHxcbiAgICBjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJlbnRyeS1wb2ludCBleHByZXNzaW9uXCIsIGxvY2F0aW9uKVxuICB9XG5cbiAgbGV0IGFyZ3VtZW50ID0gY2FsbC5hcmd1bWVudHNbMF1cblxuICBpZiAoYXJndW1lbnQudHlwZSA9PSBcIlNwcmVhZEVsZW1lbnRcIiB8fCBhcmd1bWVudC50eXBlID09IFwiQXJndW1lbnRQbGFjZWhvbGRlclwiKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBhcmd1bWVudC50eXBlLCBub2RlTG9jYXRpb24oYXJndW1lbnQsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG5cbiAgaWYgKGFyZ3VtZW50LnR5cGUgPT0gXCJDYWxsRXhwcmVzc2lvblwiICYmIGFyZ3VtZW50LmNhbGxlZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiICYmICFhcmd1bWVudC5jYWxsZWUuY29tcHV0ZWQgJiZcbiAgICAhYXJndW1lbnQuY2FsbGVlLm9wdGlvbmFsICYmIGFyZ3VtZW50LmNhbGxlZS5vYmplY3QudHlwZSAhPSBcIlN1cGVyXCIgJiYgYXJndW1lbnQuY2FsbGVlLnByb3BlcnR5LnR5cGUgPT0gXCJJZGVudGlmaWVyXCIgJiZcbiAgICBhcmd1bWVudC5jYWxsZWUucHJvcGVydHkubmFtZSA9PSBcInRvU3RyaW5nXCIgJiYgIWFyZ3VtZW50Lm9wdGlvbmFsICYmICFhcmd1bWVudC50eXBlQXJndW1lbnRzICYmXG4gICAgIWFyZ3VtZW50LnR5cGVQYXJhbWV0ZXJzICYmIGFyZ3VtZW50LmFyZ3VtZW50cy5sZW5ndGggPT0gMCkge1xuICAgIGlmICghY2Fub25pY2FsWmVyb1JlcXVpcmVkIHx8ICFoYXNDYW5vbmljYWxaZXJvUmVjZWl2ZXJXcmFwcGVyKGFyZ3VtZW50LmNhbGxlZS5vYmplY3QsIGFyZ3VtZW50KSkge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImVudHJ5LXBvaW50IHF1YWxpZmllZCBjYWxsXCIsIG5vZGVMb2NhdGlvbihhcmd1bWVudC5jYWxsZWUucHJvcGVydHksIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIH1cbiAgICBhcmd1bWVudCA9IGFyZ3VtZW50LmNhbGxlZS5vYmplY3RcbiAgfVxuXG4gIHJldHVybiB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24oYXJndW1lbnQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjb250ZXh0KSwga2luZDogXCJQcmludFN0YXRlbWVudFwiLCBsb2NhdGlvbn1cbn1cblxuLyoqXG4gKiBQYXJzZXMgSmF2YVNjcmlwdCBvciBUeXBlU2NyaXB0IGludG8gdGhlIHNoYXJlZCBzZW1hbnRpYyBtb2R1bGUuXG4gKiBAcGFyYW0ge29iamVjdH0gaW5wdXQgLSBQYXJzZXIgaW5wdXQuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGlucHV0Lmxhbmd1YWdlIC0gRnJvbnRlbmQgbGFuZ3VhZ2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQuc291cmNlIC0gU291cmNlIHRleHQuXG4gKiBAcGFyYW0ge3JlYWRvbmx5IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdENhcGFiaWxpdHlEZWNsYXJhdGlvbltdfSBbaW5wdXQuY2FwYWJpbGl0aWVzXSAtIENvbXBpbGVyLWF1dGhvcml6ZWQgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHt7aXNFbnRyeTogYm9vbGVhbiwgZnVuY3Rpb25zOiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9uPiwgcmVjb3JkczogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24+LCBlcnJvcnM/OiBNYXA8c3RyaW5nLCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5FcnJvckRlY2xhcmF0aW9uPiwgdmFsdWVSZWNvcmRzPzogTWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24+fX0gW2lucHV0LnByb2dyYW1dIC0gUmVzb2x2ZWQgcHJvZ3JhbSBpbXBvcnRzIGFuZCBlbnRyeSByb2xlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBTZW1hbnRpYyBtb2R1bGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUphdmFTY3JpcHRUeXBlU2NyaXB0KHtjYXBhYmlsaXRpZXMgPSBbXSwgZmlsZW5hbWUsIGxhbmd1YWdlLCBzb3VyY2UsIHByb2dyYW19KSB7XG4gIGNvbnN0IGZpbGUgPSBwYXJzZUJhYmVsU291cmNlKHtmaWxlbmFtZSwgbGFuZ3VhZ2UsIHNvdXJjZSwgc291cmNlVHlwZTogcHJvZ3JhbSA/IFwibW9kdWxlXCIgOiBcInNjcmlwdFwifSlcbiAgY29uc3QgdG9rZW5zID0gZmlsZS50b2tlbnMgPz8gW11cbiAgY29uc3QgdG9rZW5JbmRleCA9IHtieVN0YXJ0OiBuZXcgTWFwKHRva2Vucy5tYXAoKHRva2VuKSA9PiBbdG9rZW4uc3RhcnQsIHRva2VuXSkpLCB0b2tlbnN9XG4gIGNvbnN0IGNhbm9uaWNhbFplcm9SZXF1aXJlZCA9IHBhcnNlclRyZWVSZXF1aXJlc0Nhbm9uaWNhbFplcm8oZmlsZS5wcm9ncmFtKVxuXG4gIHJlbWVtYmVyVG9rZW5zKGZpbGUsIHRva2VuSW5kZXgpXG4gIGNvbnN0IG51bGxDaGVja09wdE91dCA9IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiXG4gICAgPyBmaWxlLmNvbW1lbnRzPy5maW5kKChjb21tZW50KSA9PiBjb21tZW50LnZhbHVlLnRyaW0oKSA9PSBcIkB0cy1ub2NoZWNrXCIpXG4gICAgOiB1bmRlZmluZWRcblxuICBpZiAobnVsbENoZWNrT3B0T3V0KSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImRpc2FibGVkIFR5cGVTY3JpcHQgY2hlY2tpbmcgZGlyZWN0aXZlXCIsIGxvY2F0aW9uRnJvbU9mZnNldHMoXG4gICAgICBmaWxlbmFtZSxcbiAgICAgIHNvdXJjZSxcbiAgICAgIG51bGxDaGVja09wdE91dC5zdGFydCA/PyAwLFxuICAgICAgbnVsbENoZWNrT3B0T3V0LmVuZCA/PyBzb3VyY2UubGVuZ3RoXG4gICAgKSlcbiAgfVxuICBpZiAoZmlsZS5wcm9ncmFtLmRpcmVjdGl2ZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJ0b3AtbGV2ZWwgZGlyZWN0aXZlXCIsIG5vZGVMb2NhdGlvbihmaWxlLnByb2dyYW0uZGlyZWN0aXZlc1swXSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuU3RhdGVtZW50W119ICovXG4gIGxldCBzZW1hbnRpY05vZGVzID0gW11cblxuICBmb3IgKGNvbnN0IG5vZGUgb2YgZmlsZS5wcm9ncmFtLmJvZHkpIHtcbiAgICBpZiAobm9kZS50eXBlID09IFwiSW1wb3J0RGVjbGFyYXRpb25cIikge1xuICAgICAgaWYgKCFwcm9ncmFtKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiaW1wb3J0IGRlY2xhcmF0aW9uXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJFeHBvcnROYW1lZERlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGlmICghcHJvZ3JhbSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImV4cG9ydCBkZWNsYXJhdGlvblwiLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBpZiAobm9kZS5zb3VyY2UgfHwgbm9kZS5kZWNsYXJhdGlvbiAmJiAhW1wiQ2xhc3NEZWNsYXJhdGlvblwiLCBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIl0uaW5jbHVkZXMobm9kZS5kZWNsYXJhdGlvbi50eXBlKSkge1xuICAgICAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwicmUtZXhwb3J0IG9yIHVuc3VwcG9ydGVkIGV4cG9ydGVkIGRlY2xhcmF0aW9uXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIH1cbiAgICAgIGlmIChub2RlLmRlY2xhcmF0aW9uKSB7XG4gICAgICAgIGlmICghbm9kZS5kZWNsYXJhdGlvbi5sZWFkaW5nQ29tbWVudHMgJiYgbm9kZS5sZWFkaW5nQ29tbWVudHMpIG5vZGUuZGVjbGFyYXRpb24ubGVhZGluZ0NvbW1lbnRzID0gbm9kZS5sZWFkaW5nQ29tbWVudHNcbiAgICAgICAgc2VtYW50aWNOb2Rlcy5wdXNoKC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkNsYXNzRGVjbGFyYXRpb24gfCBpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gKi8gKG5vZGUuZGVjbGFyYXRpb24pKVxuICAgICAgfVxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcIkV4cG9ydERlZmF1bHREZWNsYXJhdGlvblwiIHx8IG5vZGUudHlwZSA9PSBcIkV4cG9ydEFsbERlY2xhcmF0aW9uXCIpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIHNlbWFudGljTm9kZXMucHVzaChub2RlKVxuICB9XG4gIHNlbWFudGljTm9kZXMgPSB0YXNrMDM0SmF2YVNjcmlwdE5vZGVzKHNlbWFudGljTm9kZXMsIGNhcGFiaWxpdGllcywgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGNsYXNzTm9kZXMgPSBzZW1hbnRpY05vZGVzLmZpbHRlcigobm9kZSkgPT4gbm9kZS50eXBlID09IFwiQ2xhc3NEZWNsYXJhdGlvblwiKVxuICBjb25zdCBlcnJvck5vZGVzID0gY2xhc3NOb2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUuc3VwZXJDbGFzcz8udHlwZSA9PSBcIklkZW50aWZpZXJcIiAmJiBub2RlLnN1cGVyQ2xhc3MubmFtZSA9PSBcIkVycm9yXCIpXG4gIGNvbnN0IHJlZmVyZW5jZUNsYXNzTm9kZXMgPSBjbGFzc05vZGVzLmZpbHRlcigobm9kZSkgPT4gIWVycm9yTm9kZXMuaW5jbHVkZXMobm9kZSkgJiZcbiAgICBub2RlLmJvZHkuYm9keS5zb21lKChtZW1iZXIpID0+IG1lbWJlci50eXBlID09IFwiQ2xhc3NQcm9wZXJ0eVwiIHx8IG1lbWJlci50eXBlID09IFwiQ2xhc3NQcml2YXRlUHJvcGVydHlcIikpXG4gIGNvbnN0IHJlY29yZE5vZGVzID0gY2xhc3NOb2Rlcy5maWx0ZXIoKG5vZGUpID0+ICFlcnJvck5vZGVzLmluY2x1ZGVzKG5vZGUpICYmICFyZWZlcmVuY2VDbGFzc05vZGVzLmluY2x1ZGVzKG5vZGUpKVxuICBjb25zdCBlcnJvckRlY2xhcmF0aW9ucyA9IGVycm9yTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gKHtcbiAgICBpZDogYGVycm9yOiR7aW5kZXh9YCxcbiAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJFcnJvckRlY2xhcmF0aW9uXCIpLFxuICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgbmFtZTogbm9kZS5pZD8ubmFtZSA/PyBcIlwiXG4gIH0pKVxuICBjb25zdCByZWNvcmREZWNsYXJhdGlvbnMgPSByZWNvcmROb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiB7XG4gICAgY29uc3QgaWQgPSBgcmVjb3JkOiR7aW5kZXh9YFxuICAgIGNvbnN0IHR5cGVQYXJhbWV0ZXJzID0gbGFuZ3VhZ2UgPT0gXCJ0eXBlc2NyaXB0XCJcbiAgICAgID8gdHlwZVNjcmlwdFR5cGVQYXJhbWV0ZXJzKC8qKiBAdHlwZSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlRTVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHwgbnVsbCB8IHVuZGVmaW5lZH0gKi8gKG5vZGUudHlwZVBhcmFtZXRlcnMpLCBpZCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICAgIDogY2xhc3NKc2RvY1R5cGVQYXJhbWV0ZXJzKG5vZGUsIGlkLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpZWxkczogW10sXG4gICAgICBpZCxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlJlY29yZERlY2xhcmF0aW9uXCIpLFxuICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIG5hbWU6IG5vZGUuaWQ/Lm5hbWUgPz8gXCJcIixcbiAgICAgIC4uLih0eXBlUGFyYW1ldGVycyA/IHt0eXBlUGFyYW1ldGVyc30gOiB7fSlcbiAgICB9XG4gIH0pXG4gIGNvbnN0IGNsYXNzRGVjbGFyYXRpb25zID0gcmVmZXJlbmNlQ2xhc3NOb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiAoe1xuICAgIGNvbnN0cnVjdG9yOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkNvbnN0cnVjdG9yRGVjbGFyYXRpb259ICovICh7fSksXG4gICAgZmllbGRzOiBbXSwgaWQ6IGBjbGFzczoke2luZGV4fWAsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkNsYXNzRGVjbGFyYXRpb25cIiksXG4gICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSwgbWV0aG9kczogW10sIG5hbWU6IG5vZGUuaWQ/Lm5hbWUgPz8gXCJcIlxuICB9KSlcbiAgY29uc3QgcmVjb3JkTmFtZXMgPSAvKiogQHR5cGUge01hcDxzdHJpbmcsIGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlJlY29yZERlY2xhcmF0aW9uIHwgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQ2xhc3NEZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVmZmVjdFJlc291cmNlRGVjbGFyYXRpb24+fSAqLyAoXG4gICAgbmV3IE1hcChwcm9ncmFtPy5yZWNvcmRzID8/IFtdKSlcbiAgZm9yIChjb25zdCByZXNvdXJjZSBvZiBjYXBhYmlsaXRpZXMuZmxhdE1hcCgoe3Jlc291cmNlc30pID0+IHJlc291cmNlcykpIHJlY29yZE5hbWVzLnNldChyZXNvdXJjZS5uYW1lLCByZXNvdXJjZSlcbiAgY29uc3QgdmFsdWVSZWNvcmROYW1lcyA9IC8qKiBAdHlwZSB7TWFwPHN0cmluZywgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUmVjb3JkRGVjbGFyYXRpb24gfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5DbGFzc0RlY2xhcmF0aW9uPn0gKi8gKFxuICAgIG5ldyBNYXAocHJvZ3JhbT8udmFsdWVSZWNvcmRzID8/IHByb2dyYW0/LnJlY29yZHMgPz8gW10pKVxuICBjb25zdCBlcnJvck5hbWVzID0gbmV3IE1hcChwcm9ncmFtPy5lcnJvcnMgPz8gW10pXG4gIGZvciAoY29uc3QgZmFpbHVyZSBvZiBjYXBhYmlsaXRpZXMuZmxhdE1hcCgoe2ZhaWx1cmVzfSkgPT4gZmFpbHVyZXMpKSB7XG4gICAgZXJyb3JOYW1lcy5zZXQoZmFpbHVyZS5uYW1lLCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVycm9yRGVjbGFyYXRpb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChmYWlsdXJlKSkpXG4gIH1cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBlcnJvckRlY2xhcmF0aW9ucykgZXJyb3JOYW1lcy5zZXQoZGVjbGFyYXRpb24ubmFtZSwgZGVjbGFyYXRpb24pXG4gIGNvbnN0IGVycm9yc0J5SWQgPSBuZXcgTWFwKFsuLi5lcnJvck5hbWVzLnZhbHVlcygpXS5tYXAoKGRlY2xhcmF0aW9uKSA9PiBbLyoqIEB0eXBlIHtzdHJpbmd9ICovIChkZWNsYXJhdGlvbi5pZCksIGRlY2xhcmF0aW9uXSkpXG4gIGNvbnN0IGVycm9ycyA9IGVycm9yTm9kZXMubWFwKChub2RlLCBpbmRleCkgPT4gY29udmVydEphdmFTY3JpcHRFcnJvcihub2RlLCBlcnJvckRlY2xhcmF0aW9uc1tpbmRleF0sIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiByZWNvcmREZWNsYXJhdGlvbnMpIHJlY29yZE5hbWVzLnNldChkZWNsYXJhdGlvbi5uYW1lLCBkZWNsYXJhdGlvbilcbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiByZWNvcmREZWNsYXJhdGlvbnMpIHZhbHVlUmVjb3JkTmFtZXMuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uKVxuICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGNsYXNzRGVjbGFyYXRpb25zKSByZWNvcmROYW1lcy5zZXQoZGVjbGFyYXRpb24ubmFtZSwgZGVjbGFyYXRpb24pXG4gIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgY2xhc3NEZWNsYXJhdGlvbnMpIHZhbHVlUmVjb3JkTmFtZXMuc2V0KGRlY2xhcmF0aW9uLm5hbWUsIGRlY2xhcmF0aW9uKVxuICBjb25zdCB2YWx1ZVJlY29yZHNCeUlkID0gbmV3IE1hcChyZWNvcmREZWNsYXJhdGlvbnMubWFwKChkZWNsYXJhdGlvbikgPT4gWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbl0pKVxuICBjb25zdCBjbGFzc2VzQnlJZCA9IG5ldyBNYXAoY2xhc3NEZWNsYXJhdGlvbnMubWFwKChkZWNsYXJhdGlvbikgPT4gWy8qKiBAdHlwZSB7c3RyaW5nfSAqLyAoZGVjbGFyYXRpb24uaWQpLCBkZWNsYXJhdGlvbl0pKVxuICBjb25zdCBjbGFzc2VzID0gcmVmZXJlbmNlQ2xhc3NOb2Rlcy5tYXAoKG5vZGUsIGluZGV4KSA9PiBwcmVkZWNsYXJlUmVmZXJlbmNlQ2xhc3MoXG4gICAgbm9kZSwgY2xhc3NEZWNsYXJhdGlvbnNbaW5kZXhdLCByZWNvcmROYW1lcywgbGFuZ3VhZ2UsIGZpbGVuYW1lLCBzb3VyY2VcbiAgKSlcbiAgY29uc3QgZnVuY3Rpb25Ob2RlcyA9IHNlbWFudGljTm9kZXMuZmlsdGVyKChub2RlKSA9PiBub2RlLnR5cGUgPT0gXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIpXG4gIGNvbnN0IHNpZ25hdHVyZXMgPSBmdW5jdGlvbk5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+XG4gICAgY29udmVydEZ1bmN0aW9uU2lnbmF0dXJlKG5vZGUsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCByZWNvcmROYW1lcywgYGZ1bmN0aW9uOiR7aW5kZXh9YCkpXG4gIGNvbnN0IGZ1bmN0aW9uU2lnbmF0dXJlcyA9IG5ldyBNYXAoWy4uLnByb2dyYW0/LmZ1bmN0aW9ucyA/PyBbXV0ubWFwKChbbG9jYWxOYW1lLCBkZWNsYXJhdGlvbl0pID0+IFtsb2NhbE5hbWUsIHtcbiAgICBsb2NhdGlvbjogZGVjbGFyYXRpb24ubG9jYXRpb24sXG4gICAgbmFtZTogbG9jYWxOYW1lLFxuICAgIG5hbWVMb2NhdGlvbjogZGVjbGFyYXRpb24ubG9jYXRpb24sXG4gICAgcGFyYW1ldGVyczogZGVjbGFyYXRpb24ucGFyYW1ldGVycyxcbiAgICByZXR1cm5UeXBlOiBkZWNsYXJhdGlvbi5yZXR1cm5UeXBlLFxuICAgIC4uLihkZWNsYXJhdGlvbi50eXBlUGFyYW1ldGVycyA/IHt0eXBlUGFyYW1ldGVyczogZGVjbGFyYXRpb24udHlwZVBhcmFtZXRlcnN9IDoge30pXG4gIH1dKSlcbiAgZm9yIChjb25zdCBvcGVyYXRpb24gb2YgY2FwYWJpbGl0aWVzLmZsYXRNYXAoKHtvcGVyYXRpb25zfSkgPT4gb3BlcmF0aW9ucykpIHtcbiAgICBpZiAoIWZ1bmN0aW9uU2lnbmF0dXJlcy5oYXMob3BlcmF0aW9uLm5hbWUpKSBmdW5jdGlvblNpZ25hdHVyZXMuc2V0KG9wZXJhdGlvbi5uYW1lLCB7XG4gICAgICBsb2NhdGlvbjogbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBuYW1lOiBvcGVyYXRpb24ubmFtZSxcbiAgICAgIG5hbWVMb2NhdGlvbjogbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBwYXJhbWV0ZXJzOiBvcGVyYXRpb24ucGFyYW1ldGVycy5tYXAoKHBhcmFtZXRlcikgPT4gKHsuLi5wYXJhbWV0ZXIsIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IG1vZHVsZUxvY2F0aW9uKGZpbGVuYW1lLCBzb3VyY2UpfSkpLFxuICAgICAgcmV0dXJuVHlwZTogb3BlcmF0aW9uLnJldHVyblR5cGVcbiAgICB9KVxuICB9XG4gIGZvciAoY29uc3Qgc2lnbmF0dXJlIG9mIHNpZ25hdHVyZXMpIGZ1bmN0aW9uU2lnbmF0dXJlcy5zZXQoc2lnbmF0dXJlLm5hbWUsIHNpZ25hdHVyZSlcbiAgY29uc3QgcmVjb3JkcyA9IHJlY29yZE5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+IGxhbmd1YWdlID09IFwidHlwZXNjcmlwdFwiXG4gICAgPyBjb252ZXJ0VHlwZVNjcmlwdFJlY29yZChub2RlLCByZWNvcmREZWNsYXJhdGlvbnNbaW5kZXhdLCByZWNvcmROYW1lcywgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICA6IGNvbnZlcnRKYXZhU2NyaXB0UmVjb3JkKG5vZGUsIHJlY29yZERlY2xhcmF0aW9uc1tpbmRleF0sIHJlY29yZE5hbWVzLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHJlZmVyZW5jZUNsYXNzTm9kZXMubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29udmVydFJlZmVyZW5jZUNsYXNzQm9kaWVzKHJlZmVyZW5jZUNsYXNzTm9kZXNbaW5kZXhdLCBjbGFzc2VzW2luZGV4XSwgcmVjb3JkTmFtZXMsIHZhbHVlUmVjb3JkTmFtZXMsXG4gICAgICB2YWx1ZVJlY29yZHNCeUlkLCBjbGFzc2VzQnlJZCwgZnVuY3Rpb25TaWduYXR1cmVzLCBlcnJvck5hbWVzLCBlcnJvcnNCeUlkLCBsYW5ndWFnZSwgZmlsZW5hbWUsIHNvdXJjZSxcbiAgICAgIGNhbm9uaWNhbFplcm9SZXF1aXJlZClcbiAgfVxuICBjb25zdCBmdW5jdGlvbnMgPSBmdW5jdGlvbk5vZGVzLm1hcCgobm9kZSwgaW5kZXgpID0+XG4gICAgY29udmVydEZ1bmN0aW9uKG5vZGUsIHNpZ25hdHVyZXNbaW5kZXhdLCBmdW5jdGlvblNpZ25hdHVyZXMsIHJlY29yZE5hbWVzLCB2YWx1ZVJlY29yZE5hbWVzLCB2YWx1ZVJlY29yZHNCeUlkLCBjbGFzc2VzQnlJZCxcbiAgICAgIGVycm9yTmFtZXMsIGVycm9yc0J5SWQsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlLCBjYW5vbmljYWxaZXJvUmVxdWlyZWQpKVxuICBjb25zdCBlbnRyeU5vZGVzID0gc2VtYW50aWNOb2Rlcy5maWx0ZXIoKG5vZGUpID0+IG5vZGUudHlwZSAhPSBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiAmJiBub2RlLnR5cGUgIT0gXCJDbGFzc0RlY2xhcmF0aW9uXCIpXG4gIGNvbnN0IGxvY2F0aW9uID0gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAocHJvZ3JhbSAmJiAhcHJvZ3JhbS5pc0VudHJ5ICYmIGVudHJ5Tm9kZXMubGVuZ3RoID4gMCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJ0b3AtbGV2ZWwgc2lkZSBlZmZlY3Qgb3V0c2lkZSB0aGUgc2VsZWN0ZWQgZW50cnkgbW9kdWxlXCIsIG5vZGVMb2NhdGlvbihlbnRyeU5vZGVzWzBdLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCBlbnRyeUxvY2F0aW9uID0gZW50cnlOb2Rlcy5sZW5ndGggPT0gMCA/IGxvY2F0aW9uIDogbG9jYXRpb25Gcm9tT2Zmc2V0cyhcbiAgICBmaWxlbmFtZSxcbiAgICBzb3VyY2UsXG4gICAgZW50cnlOb2Rlc1swXS5zdGFydCA/PyAwLFxuICAgIGVudHJ5Tm9kZXMuYXQoLTEpPy5lbmQgPz8gc291cmNlLmxlbmd0aFxuICApXG4gIGNvbnN0IGVudHJ5QmxvY2sgPSBjb252ZXJ0QmxvY2soXG4gICAgZW50cnlOb2RlcyxcbiAgICBsYW5ndWFnZSxcbiAgICBmaWxlbmFtZSxcbiAgICBzb3VyY2UsXG4gICAgY2Fub25pY2FsWmVyb1JlcXVpcmVkLFxuICAgIHtiaW5kaW5nczogbmV3IE1hcCgpLCBjbGFzc2VzOiBjbGFzc2VzQnlJZCwgZXJyb3JOYW1lcywgZXJyb3JzOiBlcnJvcnNCeUlkLCBmdW5jdGlvbnM6IGZ1bmN0aW9uU2lnbmF0dXJlcyxcbiAgICAgIG9yZGVyZWRNYXBEZWNsYXJhdGlvbnM6IG9yZGVyZWRNYXBEZWNsYXJhdGlvbnNGb3IoZW50cnlOb2RlcyksIHJlY29yZE5hbWVzLCByZWNvcmRzOiB2YWx1ZVJlY29yZHNCeUlkLCB2YWx1ZVJlY29yZE5hbWVzfSxcbiAgICBlbnRyeUxvY2F0aW9uXG4gIClcblxuICBpZiAoIXByb2dyYW0gJiYgZnVuY3Rpb25zLmxlbmd0aCA9PSAwICYmIGNhcGFiaWxpdGllcy5sZW5ndGggPT0gMCAmJiAhYmxvY2tSZWZlcmVuY2VzUHJvdGVjdGVkRW50cnkoZW50cnlCbG9jaykpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwibW9kdWxlIHdpdGhvdXQgYSBmdW5jdGlvblwiLCBsb2NhdGlvbilcbiAgfVxuICByZXR1cm4ge1xuICAgIGVudHJ5UG9pbnQ6IHtcbiAgICAgIGJvZHk6IGVudHJ5QmxvY2ssXG4gICAgICBraW5kOiBcIkVudHJ5UG9pbnRcIixcbiAgICAgIGxvY2F0aW9uOiBlbnRyeUxvY2F0aW9uXG4gICAgfSxcbiAgICBmdW5jdGlvbnMsXG4gICAga2luZDogXCJNb2R1bGVcIixcbiAgICBsb2NhdGlvbixcbiAgICAuLi4oZXJyb3JzLmxlbmd0aCA+IDAgPyB7ZXJyb3JzfSA6IHt9KSxcbiAgICAuLi4oY2xhc3Nlcy5sZW5ndGggPiAwID8ge2NsYXNzZXN9IDoge30pLFxuICAgIC4uLihyZWNvcmRzLmxlbmd0aCA+IDAgPyB7cmVjb3Jkc30gOiB7fSlcbiAgfVxufVxuXG4vKipcbiAqIFJlbW92ZXMgZXhhY3QgcHJvdGVjdGVkIE5vZGUgcHJvYmUgc3VwcG9ydCBiZWZvcmUgcG9ydGFibGUgY29udmVyc2lvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlN0YXRlbWVudFtdfSBub2RlcyAtIFBhcnNlZCB0b3AtbGV2ZWwgc3RhdGVtZW50cy5cbiAqIEBwYXJhbSB7cmVhZG9ubHkgaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRWZmZWN0Q2FwYWJpbGl0eURlY2xhcmF0aW9uW119IGNhcGFiaWxpdGllcyAtIEF1dGhvcml6ZWQgZGVjbGFyYXRpb25zLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBsYW5ndWFnZSAtIFNvdXJjZSBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLlN0YXRlbWVudFtdfSBQb3J0YWJsZSBzdGF0ZW1lbnRzLlxuICovXG5mdW5jdGlvbiB0YXNrMDM0SmF2YVNjcmlwdE5vZGVzKG5vZGVzLCBjYXBhYmlsaXRpZXMsIGxhbmd1YWdlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGlmICghaXNUYXNrMDM0UmVzb3VyY2VQcm9iZShjYXBhYmlsaXRpZXMpKSByZXR1cm4gbm9kZXNcbiAgY29uc3QgZmlyc3QgPSBub2Rlc1swXVxuICBjb25zdCBtYXJrZXIgPSBmaXJzdD8ubGVhZGluZ0NvbW1lbnRzPy5zb21lKChjb21tZW50KSA9PiBjb21tZW50LnR5cGUgPT0gXCJDb21tZW50QmxvY2tcIiAmJlxuICAgIGNvbW1lbnQudmFsdWUudHJpbSgpID09IFwic2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0XCIpXG5cbiAgaWYgKCFtYXJrZXIpIHJldHVybiBub2Rlc1xuICBpZiAoIWhhc0V4YWN0RWZmZWN0U3VwcG9ydChzb3VyY2UsIGxhbmd1YWdlKSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJtYWxmb3JtZWQgcHJvdGVjdGVkIFRhc2sgMDM0IHN1cHBvcnRcIiwgbm9kZUxvY2F0aW9uKGZpcnN0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCBleHBlY3RlZCA9IFtcbiAgICBbXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIsIFwiX19zZW1hbnRpZm9sZFRhc2swMzRGc1wiXSwgW1wiQ2xhc3NEZWNsYXJhdGlvblwiLCBcIlByb2JlT3BlcmF0aW9uRmFpbHVyZVwiXSxcbiAgICBbXCJDbGFzc0RlY2xhcmF0aW9uXCIsIFwiUHJvYmVBY3F1aXJlRmFpbHVyZVwiXSwgW1wiQ2xhc3NEZWNsYXJhdGlvblwiLCBcIlByb2JlUmVhZEZhaWx1cmVcIl0sXG4gICAgW1wiQ2xhc3NEZWNsYXJhdGlvblwiLCBcIlByb2JlQ2xvc2VGYWlsdXJlXCJdLCBbXCJDbGFzc0RlY2xhcmF0aW9uXCIsIFwiUHJvYmVSZXNvdXJjZUNsb3NlZFwiXSxcbiAgICBbXCJDbGFzc0RlY2xhcmF0aW9uXCIsIFwiUHJvYmVSZXNvdXJjZVwiXSwgW1wiVmFyaWFibGVEZWNsYXJhdGlvblwiLCBcIl9fc2VtYW50aWZvbGRUYXNrMDM0VHJhY2VcIl0sXG4gICAgW1wiRnVuY3Rpb25EZWNsYXJhdGlvblwiLCBcInByb2JlRWZmZWN0XCJdLCBbXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIsIFwicHJvYmVBY3F1aXJlXCJdLFxuICAgIFtcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiwgXCJwcm9iZVJlYWRcIl0sIFtcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIiwgXCJwcm9iZUNsb3NlXCJdLCBbXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIsIFwicHJvYmVUcmFjZVwiXVxuICBdXG4gIC8qKlxuICAgKiBSZWFkcyB0aGUgZGVjbGFyYXRpb24gbmFtZSB1c2VkIHRvIHZlcmlmeSBvbmUgcHJvdGVjdGVkIHN1cHBvcnQgc3RhdGVtZW50LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5TdGF0ZW1lbnQgfCB1bmRlZmluZWR9IG5vZGUgLSBDYW5kaWRhdGUgc3RhdGVtZW50LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSBEZWNsYXJlZCBuYW1lLlxuICAgKi9cbiAgY29uc3Qgbm9kZU5hbWUgPSAobm9kZSkgPT4ge1xuICAgIGlmICghbm9kZSkgcmV0dXJuIHVuZGVmaW5lZFxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJWYXJpYWJsZURlY2xhcmF0aW9uXCIgJiYgbm9kZS5kZWNsYXJhdGlvbnMubGVuZ3RoID09IDEgJiYgbm9kZS5kZWNsYXJhdGlvbnNbMF0uaWQudHlwZSA9PSBcIklkZW50aWZpZXJcIikge1xuICAgICAgcmV0dXJuIG5vZGUuZGVjbGFyYXRpb25zWzBdLmlkLm5hbWVcbiAgICB9XG4gICAgY29uc3QgaWQgPSBSZWZsZWN0LmdldChub2RlLCBcImlkXCIpXG4gICAgcmV0dXJuIGlkICYmIHR5cGVvZiBpZCA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBSZWZsZWN0LmdldChpZCwgXCJuYW1lXCIpID09IFwic3RyaW5nXCIgPyBSZWZsZWN0LmdldChpZCwgXCJuYW1lXCIpIDogdW5kZWZpbmVkXG4gIH1cbiAgY29uc3QgbWF0Y2hlcyA9IGV4cGVjdGVkLmV2ZXJ5KChbdHlwZSwgbmFtZV0sIGluZGV4KSA9PiBub2Rlc1tpbmRleF0/LnR5cGUgPT0gdHlwZSAmJiBub2RlTmFtZShub2Rlc1tpbmRleF0pID09IG5hbWUpXG4gIGNvbnN0IG5leHQgPSBub2Rlc1tleHBlY3RlZC5sZW5ndGhdXG4gIGNvbnN0IGVuZGVkID0gbmV4dD8ubGVhZGluZ0NvbW1lbnRzPy5zb21lKChjb21tZW50KSA9PiBjb21tZW50LnR5cGUgPT0gXCJDb21tZW50QmxvY2tcIiAmJlxuICAgIGNvbW1lbnQudmFsdWUudHJpbSgpID09IFwic2VtYW50aWZvbGQtdGFzazAzNC1zdXBwb3J0LWVuZFwiKVxuXG4gIGlmICghbWF0Y2hlcyB8fCBuZXh0ICYmICFlbmRlZCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJtYWxmb3JtZWQgcHJvdGVjdGVkIFRhc2sgMDM0IHN1cHBvcnRcIiwgbm9kZUxvY2F0aW9uKGZpcnN0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICByZXR1cm4gbm9kZXMuc2xpY2UoZXhwZWN0ZWQubGVuZ3RoKVxufVxuXG4vKipcbiAqIEludm9rZXMgQmFiZWwgYW5kIG5vcm1hbGl6ZXMgc3ludGF4IGZhaWx1cmVzLlxuICogQHBhcmFtIHtvYmplY3R9IGlucHV0IC0gUGFyc2VyIGlucHV0LlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LmZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtcImphdmFzY3JpcHRcIiB8IFwidHlwZXNjcmlwdFwifSBpbnB1dC5sYW5ndWFnZSAtIEZyb250ZW5kIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGlucHV0LnNvdXJjZSAtIFNvdXJjZSB0ZXh0LlxuICogQHBhcmFtIHtcIm1vZHVsZVwiIHwgXCJzY3JpcHRcIn0gaW5wdXQuc291cmNlVHlwZSAtIEV4cGxpY2l0IHBhcnNlciBnb2FsLlxuICogQHJldHVybnMge2ltcG9ydChcIkBiYWJlbC9wYXJzZXJcIikuUGFyc2VSZXN1bHQ8aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLkZpbGU+fSBCYWJlbCBmaWxlLlxuICovXG5mdW5jdGlvbiBwYXJzZUJhYmVsU291cmNlKHtmaWxlbmFtZSwgbGFuZ3VhZ2UsIHNvdXJjZSwgc291cmNlVHlwZX0pIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gcGFyc2VCYWJlbChzb3VyY2UsIHtcbiAgICAgIGFsbG93QXdhaXRPdXRzaWRlRnVuY3Rpb246IHRydWUsXG4gICAgICBwbHVnaW5zOiBsYW5ndWFnZSA9PSBcInR5cGVzY3JpcHRcIiA/IFtcImRlY29yYXRvcnMtbGVnYWN5XCIsIFwidHlwZXNjcmlwdFwiXSA6IFtcImRlY29yYXRvcnMtbGVnYWN5XCJdLFxuICAgICAgc291cmNlRmlsZW5hbWU6IGZpbGVuYW1lLFxuICAgICAgc291cmNlVHlwZSxcbiAgICAgIHRva2VuczogdHJ1ZVxuICAgIH0pXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgcmV0dXJuIHBhcnNlRmFpbHVyZShsYW5ndWFnZSwgZXJyb3IsIGJhYmVsUGFyc2VyRmFpbHVyZUxvY2F0aW9uKGVycm9yLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxufVxuXG4vKipcbiAqIFJlYWRzIG9ubHkgcGFyc2VyLW93bmVkIEVTTSBpbXBvcnQvZXhwb3J0IGRlY2xhcmF0aW9ucyBmb3IgcHJvZ3JhbSBhc3NlbWJseS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBpbnB1dCAtIFBhcnNlciBpbnB1dC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5maWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7XCJqYXZhc2NyaXB0XCIgfCBcInR5cGVzY3JpcHRcIn0gaW5wdXQubGFuZ3VhZ2UgLSBGcm9udGVuZCBsYW5ndWFnZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dC5zb3VyY2UgLSBTb3VyY2UgdGV4dC5cbiAqIEByZXR1cm5zIHt7aW1wb3J0czoge2RlY2xhcmF0aW9uTG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBpbXBvcnRlZE5hbWU6IHN0cmluZywgaW1wb3J0ZWROYW1lTG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBsb2NhbE5hbWU6IHN0cmluZywgbG9jYWxOYW1lTG9jYXRpb246IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHBhdGhMb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHNwZWNpZmllcjogc3RyaW5nLCBzdGRsaWJDYW5kaWRhdGU/OiB0cnVlLCB0eXBlT25seTogYm9vbGVhbn1bXSwgZXhwb3J0czoge2RlY2xhcmF0aW9uTG9jYXRpb24/OiBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbiwgZXhwb3J0ZWROYW1lOiBzdHJpbmcsIGV4cG9ydGVkTmFtZUxvY2F0aW9uPzogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIGxvY2FsTmFtZTogc3RyaW5nLCBsb2NhbE5hbWVMb2NhdGlvbj86IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9uLCBsb2NhdGlvbjogaW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb24sIHR5cGVPbmx5OiBib29sZWFufVtdfX0gUGFyc2VyLW93bmVkIEVTTSBtb2R1bGUgaGVhZGVyLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaW5zcGVjdEphdmFTY3JpcHRUeXBlU2NyaXB0TW9kdWxlKHtmaWxlbmFtZSwgbGFuZ3VhZ2UsIHNvdXJjZX0pIHtcbiAgY29uc3QgZmlsZSA9IHBhcnNlQmFiZWxTb3VyY2Uoe2ZpbGVuYW1lLCBsYW5ndWFnZSwgc291cmNlLCBzb3VyY2VUeXBlOiBcIm1vZHVsZVwifSlcbiAgY29uc3QgdG9rZW5zID0gZmlsZS50b2tlbnMgPz8gW11cblxuICByZW1lbWJlclRva2VucyhmaWxlLCB7YnlTdGFydDogbmV3IE1hcCh0b2tlbnMubWFwKCh0b2tlbikgPT4gW3Rva2VuLnN0YXJ0LCB0b2tlbl0pKSwgdG9rZW5zfSlcbiAgY29uc3QgY29tbW9uSnMgPSBmaW5kQ29tbW9uSnNOb2RlKGZpbGUucHJvZ3JhbSlcblxuICBpZiAoY29tbW9uSnMpIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcIkNvbW1vbkpTIHJlcXVpcmUvbW9kdWxlIGV4cG9ydHNcIiwgbm9kZUxvY2F0aW9uKGNvbW1vbkpzLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3QgaW1wb3J0cyA9IFtdXG4gIGNvbnN0IGV4cG9ydHMgPSBbXVxuXG4gIGZvciAoY29uc3Qgbm9kZSBvZiBmaWxlLnByb2dyYW0uYm9keSkge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJJbXBvcnREZWNsYXJhdGlvblwiKSB7XG4gICAgICBjb25zdCByZWxhdGl2ZSA9IG5vZGUuc291cmNlLnZhbHVlLnN0YXJ0c1dpdGgoXCIuL1wiKSB8fCBub2RlLnNvdXJjZS52YWx1ZS5zdGFydHNXaXRoKFwiLi4vXCIpXG4gICAgICBjb25zdCBzdGRsaWJDYW5kaWRhdGUgPSBub2RlLnNvdXJjZS52YWx1ZS5zdGFydHNXaXRoKFwic2VtYW50aWZvbGQ6XCIpIHx8IG5vZGUuc291cmNlLnZhbHVlLnN0YXJ0c1dpdGgoXCJub2RlOlwiKVxuXG4gICAgICBpZiAoIXJlbGF0aXZlICYmICFzdGRsaWJDYW5kaWRhdGUpIHtcbiAgICAgICAgdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwiYmFyZSBwYWNrYWdlIGltcG9ydFwiLCBub2RlTG9jYXRpb24obm9kZS5zb3VyY2UsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgfVxuICAgICAgaWYgKG5vZGUuc3BlY2lmaWVycy5sZW5ndGggPT0gMCkgdW5zdXBwb3J0ZWRTeW50YXgobGFuZ3VhZ2UsIFwic2lkZS1lZmZlY3Qtb25seSBpbXBvcnRcIiwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgICAgaWYgKChub2RlLmF0dHJpYnV0ZXM/Lmxlbmd0aCA/PyAwKSA+IDAgfHwgKG5vZGUuYXNzZXJ0aW9ucz8ubGVuZ3RoID8/IDApID4gMCB8fCBSZWZsZWN0LmdldChub2RlLCBcInBoYXNlXCIpKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImltcG9ydCBhdHRyaWJ1dGVzIG9yIHBoYXNlXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICAgIH1cbiAgICAgIGZvciAoY29uc3Qgc3BlY2lmaWVyIG9mIG5vZGUuc3BlY2lmaWVycykge1xuICAgICAgICBpZiAoc3BlY2lmaWVyLnR5cGUgIT0gXCJJbXBvcnRTcGVjaWZpZXJcIiB8fCBzcGVjaWZpZXIuaW1wb3J0ZWQudHlwZSAhPSBcIklkZW50aWZpZXJcIikge1xuICAgICAgICAgIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBzcGVjaWZpZXIudHlwZSwgbm9kZUxvY2F0aW9uKHNwZWNpZmllciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICAgIH1cbiAgICAgICAgaW1wb3J0cy5wdXNoKHtcbiAgICAgICAgICBkZWNsYXJhdGlvbkxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgICAgaW1wb3J0ZWROYW1lOiBzcGVjaWZpZXIuaW1wb3J0ZWQubmFtZSxcbiAgICAgICAgICBpbXBvcnRlZE5hbWVMb2NhdGlvbjogaWRlbnRpZmllckxvY2F0aW9uKHNwZWNpZmllci5pbXBvcnRlZCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgICAgbG9jYWxOYW1lOiBzcGVjaWZpZXIubG9jYWwubmFtZSxcbiAgICAgICAgICBsb2NhbE5hbWVMb2NhdGlvbjogaWRlbnRpZmllckxvY2F0aW9uKHNwZWNpZmllci5sb2NhbCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgICAgbG9jYXRpb246IG5vZGVMb2NhdGlvbihzcGVjaWZpZXIsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICAgIHBhdGhMb2NhdGlvbjogbm9kZUxvY2F0aW9uKG5vZGUuc291cmNlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgICBzcGVjaWZpZXI6IG5vZGUuc291cmNlLnZhbHVlLFxuICAgICAgICAgIC4uLighcmVsYXRpdmUgPyB7c3RkbGliQ2FuZGlkYXRlOiAvKiogQHR5cGUge2NvbnN0fSAqLyAodHJ1ZSl9IDoge30pLFxuICAgICAgICAgIHR5cGVPbmx5OiBub2RlLmltcG9ydEtpbmQgPT0gXCJ0eXBlXCIgfHwgc3BlY2lmaWVyLmltcG9ydEtpbmQgPT0gXCJ0eXBlXCJcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJFeHBvcnREZWZhdWx0RGVjbGFyYXRpb25cIiB8fCBub2RlLnR5cGUgPT0gXCJFeHBvcnRBbGxEZWNsYXJhdGlvblwiKSB7XG4gICAgICB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgbm9kZS50eXBlLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJFeHBvcnROYW1lZERlY2xhcmF0aW9uXCIpIGNvbnRpbnVlXG4gICAgaWYgKG5vZGUuc291cmNlKSB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJyZS1leHBvcnRcIiwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGlmIChub2RlLmV4cG9ydEtpbmQgPT0gXCJ0eXBlXCIpIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcInR5cGUtb25seSBleHBvcnRcIiwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGlmIChub2RlLmRlY2xhcmF0aW9uKSB7XG4gICAgICBpZiAobm9kZS5kZWNsYXJhdGlvbi50eXBlICE9IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiICYmIG5vZGUuZGVjbGFyYXRpb24udHlwZSAhPSBcIkNsYXNzRGVjbGFyYXRpb25cIikge1xuICAgICAgICB1bnN1cHBvcnRlZFN5bnRheChsYW5ndWFnZSwgXCJ1bnN1cHBvcnRlZCBleHBvcnRlZCBkZWNsYXJhdGlvblwiLCBub2RlTG9jYXRpb24obm9kZS5kZWNsYXJhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG4gICAgICBjb25zdCBpZGVudGlmaWVyID0gbm9kZS5kZWNsYXJhdGlvbi5pZFxuXG4gICAgICBpZiAoIWlkZW50aWZpZXIpIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcImFub255bW91cyBleHBvcnRlZCBkZWNsYXJhdGlvblwiLCBub2RlTG9jYXRpb24obm9kZS5kZWNsYXJhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBleHBvcnRzLnB1c2goe1xuICAgICAgICBkZWNsYXJhdGlvbkxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIGV4cG9ydGVkTmFtZTogaWRlbnRpZmllci5uYW1lLFxuICAgICAgICBleHBvcnRlZE5hbWVMb2NhdGlvbjogaWRlbnRpZmllckxvY2F0aW9uKGlkZW50aWZpZXIsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICBsb2NhbE5hbWU6IGlkZW50aWZpZXIubmFtZSxcbiAgICAgICAgbG9jYWxOYW1lTG9jYXRpb246IGlkZW50aWZpZXJMb2NhdGlvbihpZGVudGlmaWVyLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgbG9jYXRpb246IGlkZW50aWZpZXJMb2NhdGlvbihpZGVudGlmaWVyLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgdHlwZU9ubHk6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChmYWxzZSlcbiAgICAgIH0pXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IHNwZWNpZmllciBvZiBub2RlLnNwZWNpZmllcnMpIHtcbiAgICAgIGlmIChzcGVjaWZpZXIudHlwZSAhPSBcIkV4cG9ydFNwZWNpZmllclwiIHx8IHNwZWNpZmllci5sb2NhbC50eXBlICE9IFwiSWRlbnRpZmllclwiIHx8IHNwZWNpZmllci5leHBvcnRlZC50eXBlICE9IFwiSWRlbnRpZmllclwiKSB7XG4gICAgICAgIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBzcGVjaWZpZXIudHlwZSwgbm9kZUxvY2F0aW9uKHNwZWNpZmllciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICB9XG4gICAgICBpZiAoc3BlY2lmaWVyLmV4cG9ydEtpbmQgPT0gXCJ0eXBlXCIpIHVuc3VwcG9ydGVkU3ludGF4KGxhbmd1YWdlLCBcInR5cGUtb25seSBleHBvcnRcIiwgbm9kZUxvY2F0aW9uKHNwZWNpZmllciwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBleHBvcnRzLnB1c2goe1xuICAgICAgICBkZWNsYXJhdGlvbkxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIGV4cG9ydGVkTmFtZTogc3BlY2lmaWVyLmV4cG9ydGVkLm5hbWUsXG4gICAgICAgIGV4cG9ydGVkTmFtZUxvY2F0aW9uOiBpZGVudGlmaWVyTG9jYXRpb24oc3BlY2lmaWVyLmV4cG9ydGVkLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgICAgbG9jYWxOYW1lOiBzcGVjaWZpZXIubG9jYWwubmFtZSxcbiAgICAgICAgbG9jYWxOYW1lTG9jYXRpb246IGlkZW50aWZpZXJMb2NhdGlvbihzcGVjaWZpZXIubG9jYWwsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgICAgICBsb2NhdGlvbjogbm9kZUxvY2F0aW9uKHNwZWNpZmllciwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICAgIHR5cGVPbmx5OiAvKiogQHR5cGUge2NvbnN0fSAqLyAoZmFsc2UpXG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIGNvbnN0IGR5bmFtaWMgPSBmaW5kRmFjYWRlVW5zYWZlSmF2YVNjcmlwdE5vZGUoZmlsZS5wcm9ncmFtLCBcImR5bmFtaWNcIiwgbmV3IFNldCgpKVxuXG4gIGlmIChkeW5hbWljKSBmYWNhZGVGcm9udGVuZEZhaWx1cmUobGFuZ3VhZ2UsIFwiU1RETElCX0ZBQ0FERV9EWU5BTUlDX1JFRkVSRU5DRVwiLFxuICAgIFwiRHluYW1pYyBpbXBvcnQgY2Fubm90IHByb3ZlIGEgc3RhbmRhcmQtbGlicmFyeSBmYWNhZGUgaWRlbnRpdHkuXCIsIG5vZGVMb2NhdGlvbihkeW5hbWljLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgY29uc3Qgc3RkbGliQmluZGluZ3MgPSBuZXcgU2V0KGltcG9ydHMuZmlsdGVyKCh7c3RkbGliQ2FuZGlkYXRlfSkgPT4gc3RkbGliQ2FuZGlkYXRlKS5tYXAoKHtsb2NhbE5hbWV9KSA9PiBsb2NhbE5hbWUpKVxuXG4gIGlmIChzdGRsaWJCaW5kaW5ncy5zaXplID4gMCkge1xuICAgIGNvbnN0IG11dGF0aW9uID0gZmluZEZhY2FkZVVuc2FmZUphdmFTY3JpcHROb2RlKGZpbGUucHJvZ3JhbSwgXCJtdXRhdGlvblwiLCBzdGRsaWJCaW5kaW5ncylcblxuICAgIGlmIChtdXRhdGlvbikgZmFjYWRlRnJvbnRlbmRGYWlsdXJlKGxhbmd1YWdlLCBcIlNURExJQl9GQUNBREVfU0hBRE9XRURcIixcbiAgICAgIFwiQSBwYXJzZXItcHJvdmVkIHN0YW5kYXJkLWxpYnJhcnkgZmFjYWRlIGJpbmRpbmcgY2Fubm90IGJlIHJlYXNzaWduZWQgb3Igc2hhZG93ZWQuXCIsIG5vZGVMb2NhdGlvbihtdXRhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgY29uc3QgcmVmbGVjdGlvbiA9IGZpbmRGYWNhZGVVbnNhZmVKYXZhU2NyaXB0Tm9kZShmaWxlLnByb2dyYW0sIFwicmVmbGVjdGlvblwiLCBzdGRsaWJCaW5kaW5ncylcblxuICAgIGlmIChyZWZsZWN0aW9uKSBmYWNhZGVGcm9udGVuZEZhaWx1cmUobGFuZ3VhZ2UsIFwiU1RETElCX0ZBQ0FERV9SRUZMRUNUSU9OX1VOU1VQUE9SVEVEXCIsXG4gICAgICBcIlJlZmxlY3RpdmUgbG9va3VwIGNhbm5vdCBwcmVzZXJ2ZSBhIHByb3ZlZCBzdGFuZGFyZC1saWJyYXJ5IGZhY2FkZSBzeW1ib2wgaWRlbnRpdHkuXCIsIG5vZGVMb2NhdGlvbihyZWZsZWN0aW9uLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiB7ZXhwb3J0cywgaW1wb3J0c31cbn1cblxuLyoqXG4gKiBGaW5kcyBwYXJzZXItb3duZWQgZHluYW1pYywgbXV0YXRpbmcsIG9yIHJlZmxlY3RpdmUgY29uc3RydWN0cyByZWxldmFudCB0byBmYWNhZGUgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3Vua25vd259IHZhbHVlIC0gQmFiZWwgc3VidHJlZS5cbiAqIEBwYXJhbSB7XCJkeW5hbWljXCIgfCBcIm11dGF0aW9uXCIgfCBcInJlZmxlY3Rpb25cIn0gbW9kZSAtIFJlamVjdGVkIGNvbnN0cnVjdCBjbGFzcy5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IGJpbmRpbmdzIC0gUGFyc2VyLXByb3ZlZCBuYXRpdmUgZmFjYWRlIGJpbmRpbmdzLlxuICogQHBhcmFtIHtXZWFrU2V0PG9iamVjdD59IFtzZWVuXSAtIEN5Y2xlIGd1YXJkLlxuICogQHJldHVybnMge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Ob2RlIHwgdW5kZWZpbmVkfSBGaXJzdCByZWplY3RlZCBwYXJzZXIgbm9kZS5cbiAqL1xuZnVuY3Rpb24gZmluZEZhY2FkZVVuc2FmZUphdmFTY3JpcHROb2RlKHZhbHVlLCBtb2RlLCBiaW5kaW5ncywgc2VlbiA9IG5ldyBXZWFrU2V0KCkpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT0gXCJvYmplY3RcIiB8fCBzZWVuLmhhcyh2YWx1ZSkpIHJldHVybiB1bmRlZmluZWRcbiAgc2Vlbi5hZGQodmFsdWUpXG4gIGNvbnN0IG5vZGUgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHVua25vd24+fSAqLyAodmFsdWUpXG5cbiAgaWYgKG1vZGUgPT0gXCJkeW5hbWljXCIgJiYgbm9kZS50eXBlID09IFwiSW1wb3J0RXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3Qgc291cmNlTm9kZSA9IG5vZGUuc291cmNlXG5cbiAgICBpZiAoaXNGYWNhZGVNb2R1bGVTdHJpbmdOb2RlKHNvdXJjZU5vZGUpKSByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gKi8gKHZhbHVlKVxuICB9XG4gIGlmIChtb2RlID09IFwiZHluYW1pY1wiICYmIG5vZGUudHlwZSA9PSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgbm9kZS5jYWxsZWUgJiYgdHlwZW9mIG5vZGUuY2FsbGVlID09IFwib2JqZWN0XCIgJiZcbiAgICBSZWZsZWN0LmdldChub2RlLmNhbGxlZSwgXCJ0eXBlXCIpID09IFwiSW1wb3J0XCIpIHtcbiAgICBjb25zdCBhcmd1bWVudHNfID0gQXJyYXkuaXNBcnJheShub2RlLmFyZ3VtZW50cykgPyBub2RlLmFyZ3VtZW50cyA6IFtdXG5cbiAgICBpZiAoaXNGYWNhZGVNb2R1bGVTdHJpbmdOb2RlKGFyZ3VtZW50c19bMF0pKSByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gKi8gKHZhbHVlKVxuICB9XG4gIGlmIChtb2RlID09IFwicmVmbGVjdGlvblwiICYmIG5vZGUudHlwZSA9PSBcIkNhbGxFeHByZXNzaW9uXCIgJiYgbm9kZS5jYWxsZWUgJiYgdHlwZW9mIG5vZGUuY2FsbGVlID09IFwib2JqZWN0XCIgJiZcbiAgICBSZWZsZWN0LmdldChub2RlLmNhbGxlZSwgXCJ0eXBlXCIpID09IFwiSWRlbnRpZmllclwiICYmIFJlZmxlY3QuZ2V0KG5vZGUuY2FsbGVlLCBcIm5hbWVcIikgPT0gXCJldmFsXCIpIHtcbiAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gKi8gKHZhbHVlKVxuICB9XG4gIGlmIChtb2RlID09IFwibXV0YXRpb25cIiAmJiAobm9kZS50eXBlID09IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIiB8fCBub2RlLnR5cGUgPT0gXCJVcGRhdGVFeHByZXNzaW9uXCIpKSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gbm9kZS50eXBlID09IFwiQXNzaWdubWVudEV4cHJlc3Npb25cIiA/IG5vZGUubGVmdCA6IG5vZGUuYXJndW1lbnRcblxuICAgIGlmICh0YXJnZXQgJiYgdHlwZW9mIHRhcmdldCA9PSBcIm9iamVjdFwiICYmIFJlZmxlY3QuZ2V0KHRhcmdldCwgXCJ0eXBlXCIpID09IFwiSWRlbnRpZmllclwiICYmXG4gICAgICBiaW5kaW5ncy5oYXMoU3RyaW5nKFJlZmxlY3QuZ2V0KHRhcmdldCwgXCJuYW1lXCIpKSkpIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIkBiYWJlbC90eXBlc1wiKS5Ob2RlfSAqLyAodmFsdWUpXG4gIH1cbiAgZm9yIChjb25zdCBba2V5LCBjaGlsZF0gb2YgT2JqZWN0LmVudHJpZXMobm9kZSkpIHtcbiAgICBpZiAoW1wiZXh0cmFcIiwgXCJpbm5lckNvbW1lbnRzXCIsIFwibGVhZGluZ0NvbW1lbnRzXCIsIFwibG9jXCIsIFwidHJhaWxpbmdDb21tZW50c1wiXS5pbmNsdWRlcyhrZXkpKSBjb250aW51ZVxuICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGNoaWxkKSB7XG4gICAgICAgIGNvbnN0IGZvdW5kID0gZmluZEZhY2FkZVVuc2FmZUphdmFTY3JpcHROb2RlKGl0ZW0sIG1vZGUsIGJpbmRpbmdzLCBzZWVuKVxuXG4gICAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kXG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGZvdW5kID0gZmluZEZhY2FkZVVuc2FmZUphdmFTY3JpcHROb2RlKGNoaWxkLCBtb2RlLCBiaW5kaW5ncywgc2VlbilcblxuICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZFxufVxuXG4vKipcbiAqIENoZWNrcyBhIEJhYmVsIHN0cmluZyBsaXRlcmFsIGZvciBvbmUgY2F0YWxvZy1zdHlsZSBzdGRsaWIgbW9kdWxlIGlkZW50aXR5LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIEJhYmVsIGltcG9ydCBhcmd1bWVudC9zb3VyY2Ugbm9kZS5cbiAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBleGFjdCBsaXRlcmFsIGlzIGEgZmFjYWRlIG1vZHVsZSBjYW5kaWRhdGUuXG4gKi9cbmZ1bmN0aW9uIGlzRmFjYWRlTW9kdWxlU3RyaW5nTm9kZSh2YWx1ZSkge1xuICBpZiAoIXZhbHVlIHx8IHR5cGVvZiB2YWx1ZSAhPSBcIm9iamVjdFwiKSByZXR1cm4gZmFsc2VcbiAgY29uc3Qgbm9kZSA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgdW5rbm93bj59ICovICh2YWx1ZSlcbiAgY29uc3QgbGl0ZXJhbCA9IG5vZGUudmFsdWVcblxuICByZXR1cm4gbm9kZS50eXBlID09IFwiU3RyaW5nTGl0ZXJhbFwiICYmIHR5cGVvZiBsaXRlcmFsID09IFwic3RyaW5nXCIgJiZcbiAgICAobGl0ZXJhbC5zdGFydHNXaXRoKFwic2VtYW50aWZvbGQ6XCIpIHx8IGxpdGVyYWwuc3RhcnRzV2l0aChcIm5vZGU6XCIpKVxufVxuXG4vKipcbiAqIFRocm93cyBvbmUgc3RhYmxlIGxvY2F0ZWQgZmFjYWRlIGZyb250ZW5kIGRpYWdub3N0aWMuXG4gKiBAcGFyYW0ge1wiamF2YXNjcmlwdFwiIHwgXCJ0eXBlc2NyaXB0XCJ9IGxhbmd1YWdlIC0gU291cmNlIGxhbmd1YWdlLlxuICogQHBhcmFtIHtzdHJpbmd9IGNvZGUgLSBTdGFibGUgZGlhZ25vc3RpYyBjb2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IG1lc3NhZ2UgLSBEaWFnbm9zdGljIGRldGFpbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gUGFyc2VyLW93bmVkIGxvY2F0aW9uLlxuICogQHJldHVybnMge25ldmVyfSBBbHdheXMgdGhyb3dzLlxuICovXG5mdW5jdGlvbiBmYWNhZGVGcm9udGVuZEZhaWx1cmUobGFuZ3VhZ2UsIGNvZGUsIG1lc3NhZ2UsIGxvY2F0aW9uKSB7XG4gIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGUsIGxhbmd1YWdlLCBsb2NhdGlvbiwgbWVzc2FnZX0pXG59XG5cbi8qKlxuICogRmluZHMgQ29tbW9uSlMgY29uc3RydWN0cyB0aHJvdWdoIEJhYmVsIG5vZGVzIHJhdGhlciB0aGFuIHNvdXJjZS10ZXh0IG1hdGNoaW5nLlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIEJhYmVsIHN1YnRyZWUuXG4gKiBAcGFyYW0ge1dlYWtTZXQ8b2JqZWN0Pn0gW3NlZW5dIC0gQ3ljbGUgZ3VhcmQuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiQGJhYmVsL3R5cGVzXCIpLk5vZGUgfCB1bmRlZmluZWR9IFVuc3VwcG9ydGVkIG5vZGUuXG4gKi9cbmZ1bmN0aW9uIGZpbmRDb21tb25Kc05vZGUodmFsdWUsIHNlZW4gPSBuZXcgV2Vha1NldCgpKSB7XG4gIGlmICghdmFsdWUgfHwgdHlwZW9mIHZhbHVlICE9IFwib2JqZWN0XCIgfHwgc2Vlbi5oYXModmFsdWUpKSByZXR1cm4gdW5kZWZpbmVkXG4gIHNlZW4uYWRkKHZhbHVlKVxuICBjb25zdCBub2RlID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gKi8gKHZhbHVlKVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJDYWxsRXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3QgY2FsbGVlID0gbm9kZS5jYWxsZWVcblxuICAgIGlmIChjYWxsZWUgJiYgdHlwZW9mIGNhbGxlZSA9PSBcIm9iamVjdFwiICYmIFJlZmxlY3QuZ2V0KGNhbGxlZSwgXCJ0eXBlXCIpID09IFwiSWRlbnRpZmllclwiICYmIFJlZmxlY3QuZ2V0KGNhbGxlZSwgXCJuYW1lXCIpID09IFwicmVxdWlyZVwiKSB7XG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gKi8gKHZhbHVlKVxuICAgIH1cbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiTWVtYmVyRXhwcmVzc2lvblwiKSB7XG4gICAgY29uc3Qgb2JqZWN0ID0gbm9kZS5vYmplY3RcblxuICAgIGlmIChvYmplY3QgJiYgdHlwZW9mIG9iamVjdCA9PSBcIm9iamVjdFwiICYmIFJlZmxlY3QuZ2V0KG9iamVjdCwgXCJ0eXBlXCIpID09IFwiSWRlbnRpZmllclwiICYmXG4gICAgICBbXCJleHBvcnRzXCIsIFwibW9kdWxlXCJdLmluY2x1ZGVzKFN0cmluZyhSZWZsZWN0LmdldChvYmplY3QsIFwibmFtZVwiKSkpKSB7XG4gICAgICByZXR1cm4gLyoqIEB0eXBlIHtpbXBvcnQoXCJAYmFiZWwvdHlwZXNcIikuTm9kZX0gKi8gKHZhbHVlKVxuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IFtrZXksIGNoaWxkXSBvZiBPYmplY3QuZW50cmllcyhub2RlKSkge1xuICAgIGlmIChbXCJleHRyYVwiLCBcImlubmVyQ29tbWVudHNcIiwgXCJsZWFkaW5nQ29tbWVudHNcIiwgXCJsb2NcIiwgXCJ0cmFpbGluZ0NvbW1lbnRzXCJdLmluY2x1ZGVzKGtleSkpIGNvbnRpbnVlXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoY2hpbGQpKSB7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgY2hpbGQpIHtcbiAgICAgICAgY29uc3QgZm91bmQgPSBmaW5kQ29tbW9uSnNOb2RlKGl0ZW0sIHNlZW4pXG5cbiAgICAgICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmRcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgZm91bmQgPSBmaW5kQ29tbW9uSnNOb2RlKGNoaWxkLCBzZWVuKVxuXG4gICAgICBpZiAoZm91bmQpIHJldHVybiBmb3VuZFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB1bmRlZmluZWRcbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIEJhYmVsJ3MgemVyby1iYXNlZCBVVEYtMTYgZmFpbHVyZSBvZmZzZXQgd2hlbiBhdmFpbGFibGUuXG4gKiBAcGFyYW0ge3Vua25vd259IGVycm9yIC0gTmF0aXZlIEJhYmVsIHBhcnNlciBlcnJvci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFJlcXVlc3RlZCBzb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNvdXJjZUxvY2F0aW9ufSBGYWlsdXJlIHJhbmdlLlxuICovXG5mdW5jdGlvbiBiYWJlbFBhcnNlckZhaWx1cmVMb2NhdGlvbihlcnJvciwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIWVycm9yIHx8IHR5cGVvZiBlcnJvciAhPSBcIm9iamVjdFwiKSByZXR1cm4gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgZGlyZWN0ID0gUmVmbGVjdC5nZXQoZXJyb3IsIFwicG9zXCIpXG4gIGNvbnN0IHBhcnNlckxvY2F0aW9uID0gUmVmbGVjdC5nZXQoZXJyb3IsIFwibG9jXCIpXG4gIGNvbnN0IGxvY2F0ZWQgPSBwYXJzZXJMb2NhdGlvbiAmJiB0eXBlb2YgcGFyc2VyTG9jYXRpb24gPT0gXCJvYmplY3RcIiA/IFJlZmxlY3QuZ2V0KHBhcnNlckxvY2F0aW9uLCBcImluZGV4XCIpIDogdW5kZWZpbmVkXG4gIGNvbnN0IG9mZnNldCA9IE51bWJlci5pc1NhZmVJbnRlZ2VyKGRpcmVjdCkgPyBkaXJlY3QgOiBsb2NhdGVkXG5cbiAgaWYgKHR5cGVvZiBvZmZzZXQgIT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzU2FmZUludGVnZXIob2Zmc2V0KSB8fCBvZmZzZXQgPCAwIHx8IG9mZnNldCA+IHNvdXJjZS5sZW5ndGgpIHtcbiAgICByZXR1cm4gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgfVxuXG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKGZpbGVuYW1lLCBzb3VyY2UsIG9mZnNldCwgTWF0aC5taW4ob2Zmc2V0ICsgMSwgc291cmNlLmxlbmd0aCkpXG59XG5cbi8qKlxuICogQXNzb2NpYXRlcyBCYWJlbCBub2RlcyB3aXRoIHRoZWlyIHBhcnNlciB0b2tlbiBzdHJlYW0gd2l0aG91dCBsZWFraW5nIGl0IGludG8gc2VtYW50aWMgdmFsdWVzLlxuICogQHBhcmFtIHtvYmplY3R9IHZhbHVlIC0gQ3VycmVudCBwYXJzZXIgdmFsdWUuXG4gKiBAcGFyYW0ge0JhYmVsVG9rZW5JbmRleH0gdG9rZW5zIC0gSW5kZXhlZCBwYXJzZXIgdG9rZW5zLlxuICogQHBhcmFtIHtXZWFrU2V0PG9iamVjdD59IFt2aXNpdGVkXSAtIEN5Y2xlIHByb3RlY3Rpb24uXG4gKiBAcmV0dXJucyB7dm9pZH1cbiAqL1xuZnVuY3Rpb24gcmVtZW1iZXJUb2tlbnModmFsdWUsIHRva2VucywgdmlzaXRlZCA9IG5ldyBXZWFrU2V0KCkpIHtcbiAgaWYgKHZpc2l0ZWQuaGFzKHZhbHVlKSkgcmV0dXJuXG5cbiAgdmlzaXRlZC5hZGQodmFsdWUpXG4gIG5vZGVUb2tlbnMuc2V0KHZhbHVlLCB0b2tlbnMpXG5cbiAgZm9yIChjb25zdCBjaGlsZCBvZiBPYmplY3QudmFsdWVzKHZhbHVlKSkge1xuICAgIGlmIChBcnJheS5pc0FycmF5KGNoaWxkKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGNoaWxkKSBpZiAoaXRlbSAmJiB0eXBlb2YgaXRlbSA9PSBcIm9iamVjdFwiKSByZW1lbWJlclRva2VucyhpdGVtLCB0b2tlbnMsIHZpc2l0ZWQpXG4gICAgfSBlbHNlIGlmIChjaGlsZCAmJiB0eXBlb2YgY2hpbGQgPT0gXCJvYmplY3RcIikgcmVtZW1iZXJUb2tlbnMoY2hpbGQsIHRva2VucywgdmlzaXRlZClcbiAgfVxufVxuIl19
|