semantifold 0.4.0 → 0.6.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 +13 -7
- package/build/index.d.ts +12 -8
- package/build/index.d.ts.map +1 -1
- package/build/index.js +10 -7
- package/build/src/backends/android.d.ts +49 -0
- package/build/src/backends/android.d.ts.map +1 -0
- package/build/src/backends/android.js +1278 -0
- package/build/src/backends/identifiers.d.ts +6 -0
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +30 -1
- package/build/src/backends/ios.js +2 -2
- package/build/src/backends/kotlin.d.ts +10 -0
- package/build/src/backends/kotlin.d.ts.map +1 -1
- package/build/src/backends/kotlin.js +11 -9
- 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/program.d.ts +6 -4
- package/build/src/backends/program.d.ts.map +1 -1
- package/build/src/backends/program.js +5 -4
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +2 -1
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +20 -4
- package/build/src/backends/writer.d.ts +21 -1
- package/build/src/backends/writer.d.ts.map +1 -1
- package/build/src/backends/writer.js +25 -2
- package/build/src/backends/zig-runtime.d.ts +5 -0
- package/build/src/backends/zig-runtime.d.ts.map +1 -0
- package/build/src/backends/zig-runtime.js +92 -0
- package/build/src/backends/zig-validation.d.ts +9 -0
- package/build/src/backends/zig-validation.d.ts.map +1 -0
- package/build/src/backends/zig-validation.js +73 -0
- package/build/src/backends/zig.d.ts +42 -0
- package/build/src/backends/zig.d.ts.map +1 -0
- package/build/src/backends/zig.js +584 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +2 -1
- package/build/src/frontends/zig-parser.d.ts +31 -0
- package/build/src/frontends/zig-parser.d.ts.map +1 -0
- package/build/src/frontends/zig-parser.js +17 -0
- package/build/src/frontends/zig.d.ts +14 -0
- package/build/src/frontends/zig.d.ts.map +1 -0
- package/build/src/frontends/zig.js +970 -0
- package/build/src/language-registry.d.ts.map +1 -1
- package/build/src/language-registry.js +40 -1
- package/build/src/mapping.js +2 -2
- package/build/src/semantic/provenance.js +3 -3
- package/build/src/semantic/types.d.ts +184 -4
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +45 -3
- package/build/src/semantic/validate.js +2 -2
- package/build/src/toolchains.d.ts +6 -0
- package/build/src/toolchains.d.ts.map +1 -1
- package/build/src/toolchains.js +2 -1
- package/build/src/zig-bindings.d.ts +10 -0
- package/build/src/zig-bindings.d.ts.map +1 -0
- package/build/src/zig-bindings.js +54 -0
- package/docs/android.md +79 -0
- package/docs/architecture.md +13 -5
- package/docs/goals.md +1 -1
- package/docs/ios.md +1 -1
- package/docs/language-support.md +15 -4
- package/docs/parser-qualification.md +31 -1
- package/docs/source-maps.md +7 -3
- package/docs/specification.md +5 -0
- package/docs/testing.md +40 -3
- package/docs/zig.md +33 -0
- package/index.js +9 -6
- package/node_modules/semantifold-tree-sitter-zig-internal/LICENSE +15 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/README.md +5 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/README.md +21 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/binding.gyp +29 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/grammar.js +900 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/package.json +57 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/darwin-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/darwin-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/linux-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/linux-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/win32-arm64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/prebuilds/win32-x64/@tree-sitter-grammars+tree-sitter-zig.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/folds.scm +23 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/highlights.scm +291 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/indents.scm +22 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/queries/injections.scm +10 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/grammar.json +6570 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/node-types.json +3178 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/parser.c +169829 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/array.h +291 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/tree-sitter-zig.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/@tree-sitter-grammars/tree-sitter-zig/tree-sitter.json +38 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/README.md +128 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/binding.gyp +80 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/index.js +916 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/package.json +76 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/language.cc +106 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/node.cc +1088 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/parser.cc +306 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/query.cc +397 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/query.h +40 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree.cc +316 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/tree-sitter.d.ts +1042 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1318 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +223 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +297 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +435 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +920 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2165 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +206 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4187 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +130 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1066 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +712 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +83 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1302 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1859 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/package.json +21 -0
- package/node_modules/semantifold-tree-sitter-zig-internal/src/zig.js +134 -0
- package/package.json +11 -6
- package/src/backends/android.js +1374 -0
- package/src/backends/identifiers.js +30 -0
- package/src/backends/ios.js +1 -1
- package/src/backends/kotlin.js +11 -8
- package/src/backends/native-validation.js +1 -1
- package/src/backends/program.js +4 -3
- package/src/backends/scalars.js +1 -0
- package/src/backends/shared.js +22 -3
- package/src/backends/writer.js +27 -2
- package/src/backends/zig-runtime.js +93 -0
- package/src/backends/zig-validation.js +68 -0
- package/src/backends/zig.js +579 -0
- package/src/frontends/scalars.js +1 -0
- package/src/frontends/zig-parser.js +20 -0
- package/src/frontends/zig.js +994 -0
- package/src/language-registry.js +40 -0
- package/src/mapping.js +1 -1
- package/src/semantic/provenance.js +2 -2
- package/src/semantic/types.js +47 -2
- package/src/semantic/validate.js +1 -1
- package/src/toolchains.js +1 -0
- package/src/zig-bindings.js +46 -0
|
@@ -0,0 +1,970 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import { isZigIdentifier } from "../backends/identifiers.js";
|
|
3
|
+
import { generateZigProject } from "../backends/zig.js";
|
|
4
|
+
import { zigRuntime } from "../backends/zig-runtime.js";
|
|
5
|
+
import { maximumZigSourceLength } from "../backends/zig-validation.js";
|
|
6
|
+
import { missingType, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
|
|
7
|
+
import { createCoordinateIndex, indexedPointAt } from "../semantic/location.js";
|
|
8
|
+
import { withAdaptedOperation } from "../semantic/operators.js";
|
|
9
|
+
import { withParserRanges } from "../semantic/provenance.js";
|
|
10
|
+
import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
|
|
11
|
+
import { validateParsedModule } from "../semantic/validate.js";
|
|
12
|
+
import { sourceScalarType } from "./scalars.js";
|
|
13
|
+
import { parseZigCst } from "./zig-parser.js";
|
|
14
|
+
import { collectZigBindingUsage } from "../zig-bindings.js";
|
|
15
|
+
/** @typedef {import("./zig-parser.js").CstNode} CstNode */
|
|
16
|
+
/** @typedef {import("../semantic/types.js").Expression} Expression */
|
|
17
|
+
/** @typedef {import("../semantic/types.js").Statement} Statement */
|
|
18
|
+
/** @typedef {import("../semantic/types.js").FunctionReturnTypeName} Scalar */
|
|
19
|
+
const binaryOperations = new Map([
|
|
20
|
+
["+", "Add"], ["-", "Subtract"], ["*", "Multiply"], ["==", "Equal"], ["!=", "NotEqual"],
|
|
21
|
+
["<", "LessThan"], ["<=", "LessThanOrEqual"], [">", "GreaterThan"], [">=", "GreaterThanOrEqual"],
|
|
22
|
+
["and", "And"], ["or", "Or"]
|
|
23
|
+
]);
|
|
24
|
+
const helperOperations = new Map([
|
|
25
|
+
["semantifold_integer_add", "Add"], ["semantifold_integer_subtract", "Subtract"],
|
|
26
|
+
["semantifold_integer_multiply", "Multiply"], ["semantifold_string_concat", "Add"],
|
|
27
|
+
["semantifold_string_equal", "Equal"], ["semantifold_string_not_equal", "NotEqual"]
|
|
28
|
+
]);
|
|
29
|
+
const operationSpellings = new Map([
|
|
30
|
+
["IntegerAdd", "semantifold_integer_add"], ["IntegerSubtract", "semantifold_integer_subtract"],
|
|
31
|
+
["IntegerMultiply", "semantifold_integer_multiply"], ["IntegerNegate", "semantifold_integer_negate"],
|
|
32
|
+
["IntegerEqual", "=="], ["IntegerNotEqual", "!="], ["IntegerLessThan", "<"],
|
|
33
|
+
["IntegerLessThanOrEqual", "<="], ["IntegerGreaterThan", ">"], ["IntegerGreaterThanOrEqual", ">="],
|
|
34
|
+
["BooleanEqual", "=="], ["BooleanNotEqual", "!="], ["BooleanAnd", "and"], ["BooleanOr", "or"], ["BooleanNot", "!"],
|
|
35
|
+
["StringConcat", "semantifold_string_concat"], ["StringEqual", "semantifold_string_equal"],
|
|
36
|
+
["StringNotEqual", "semantifold_string_not_equal"]
|
|
37
|
+
]);
|
|
38
|
+
/** Consumes the complete qualified Zig CST and retains exact generated-shell constraints. */
|
|
39
|
+
class ZigReader {
|
|
40
|
+
/**
|
|
41
|
+
* Creates a reader over one complete parser snapshot.
|
|
42
|
+
* @param {string} filename - Logical source filename.
|
|
43
|
+
* @param {string} source - Exact Zig source text.
|
|
44
|
+
*/
|
|
45
|
+
constructor(filename, source) {
|
|
46
|
+
this.filename = filename;
|
|
47
|
+
this.source = source;
|
|
48
|
+
this.coordinates = createCoordinateIndex(source);
|
|
49
|
+
this.generated = false;
|
|
50
|
+
/** @type {Map<string, Expression> | undefined} */
|
|
51
|
+
this.temporaryExpressions = undefined;
|
|
52
|
+
/** @type {Set<string> | undefined} */
|
|
53
|
+
this.temporaryNames = undefined;
|
|
54
|
+
/** @type {Map<Expression, {node: CstNode, spelling: string}>} */
|
|
55
|
+
this.operations = new Map();
|
|
56
|
+
/** @type {Map<Statement, {node: CstNode, type: string}>} */
|
|
57
|
+
this.prints = new Map();
|
|
58
|
+
/** @type {Map<string, Scalar>} */
|
|
59
|
+
this.functions = new Map();
|
|
60
|
+
/** @type {Map<import("../semantic/types.js").Parameter | import("../semantic/types.js").LocalDeclaration, "use" | "address" | "none">} */
|
|
61
|
+
this.scaffolds = new Map();
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Converts a parser node boundary to a semantic location.
|
|
65
|
+
* @param {CstNode} node - Parser node.
|
|
66
|
+
* @returns {import("../semantic/types.js").SourceLocation} UTF-16 location.
|
|
67
|
+
*/
|
|
68
|
+
location(node) {
|
|
69
|
+
return { filename: this.filename, start: indexedPointAt(this.coordinates, node.startIndex), end: indexedPointAt(this.coordinates, node.endIndex) };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Reads the exact source spelling owned by a parser node.
|
|
73
|
+
* @param {CstNode} node - Parser node.
|
|
74
|
+
* @returns {string} Node source text.
|
|
75
|
+
*/
|
|
76
|
+
text(node) {
|
|
77
|
+
return this.source.slice(node.startIndex, node.endIndex);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Reads one generated line-comment marker independent of the source newline convention.
|
|
81
|
+
* @param {CstNode} node - Marker comment node.
|
|
82
|
+
* @returns {string} Marker spelling without a parser-owned trailing carriage return.
|
|
83
|
+
*/
|
|
84
|
+
marker(node) {
|
|
85
|
+
return this.text(node).replace(/\r$/u, "");
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Raises a located unsupported-syntax diagnostic.
|
|
89
|
+
* @param {CstNode} node - Rejected parser node.
|
|
90
|
+
* @param {string} [detail] - Diagnostic detail.
|
|
91
|
+
* @returns {never} This function always throws.
|
|
92
|
+
*/
|
|
93
|
+
fail(node, detail = node.type) {
|
|
94
|
+
unsupportedSyntax("zig", detail, this.location(node));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Exhaustively rejects recovery, unexpected extras, directives, and excessive nesting.
|
|
98
|
+
* @param {CstNode} node - Current CST node.
|
|
99
|
+
* @param {number} [depth] - Current nesting depth.
|
|
100
|
+
*/
|
|
101
|
+
validateTree(node, depth = 0) {
|
|
102
|
+
if (depth > 512)
|
|
103
|
+
this.fail(node, "Zig CST exceeds the 512-level traversal limit");
|
|
104
|
+
for (const { node: child } of node.children)
|
|
105
|
+
this.validateTree(child, depth + 1);
|
|
106
|
+
if (node.error || node.missing || node.hasError) {
|
|
107
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "zig", location: this.location(node), message: `Zig parser recovery at '${node.type}'.` });
|
|
108
|
+
}
|
|
109
|
+
if (node.extra && node.type != "comment")
|
|
110
|
+
this.fail(node, "unexpected extra parser child");
|
|
111
|
+
if (node.type == "comment" && (/^\s*\/\/[/!]/u.test(this.text(node)) || /^\s*\/\/\s*zig fmt:/u.test(this.text(node)))) {
|
|
112
|
+
this.fail(node, "doc or formatter-directive comment");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Returns every non-comment child without hiding syntax edges.
|
|
117
|
+
* @param {CstNode} node - Parent parser node.
|
|
118
|
+
* @returns {CstNode[]} Ordered non-comment children.
|
|
119
|
+
*/
|
|
120
|
+
parts(node) {
|
|
121
|
+
return node.children.map(({ node: child }) => child).filter(child => child.type != "comment");
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Retains compiler-owned scaffold markers while ignoring ordinary inert comments.
|
|
125
|
+
* @param {CstNode} node - Parent parser node.
|
|
126
|
+
* @returns {CstNode[]} Complete significant child list.
|
|
127
|
+
*/
|
|
128
|
+
significant(node) {
|
|
129
|
+
return node.children.map(({ node: child }) => child).filter(child => child.type != "comment" || /semantifold:/u.test(this.text(child)));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Requires exactly one parser field edge.
|
|
133
|
+
* @param {CstNode} node - Parent parser node.
|
|
134
|
+
* @param {string} name - Required field name.
|
|
135
|
+
* @returns {CstNode} Field child.
|
|
136
|
+
*/
|
|
137
|
+
field(node, name) {
|
|
138
|
+
const edges = node.children.filter(({ field }) => field == name);
|
|
139
|
+
if (edges.length != 1)
|
|
140
|
+
this.fail(node, `expected one '${name}' field`);
|
|
141
|
+
return edges[0].node;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Requires an exact ordered child/token shape.
|
|
145
|
+
* @param {CstNode} node - Parser node to check.
|
|
146
|
+
* @param {(CstNode | string)[]} expected - Expected node identities or token types.
|
|
147
|
+
*/
|
|
148
|
+
shape(node, expected) {
|
|
149
|
+
const parts = this.parts(node);
|
|
150
|
+
if (parts.length != expected.length || parts.some((child, index) => typeof expected[index] == "string" ? child.type != expected[index] || !child.named && this.text(child) != expected[index] : child !== expected[index])) {
|
|
151
|
+
this.fail(node, `${node.type} child shape`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Validates and returns one ordinary Zig identifier.
|
|
156
|
+
* @param {CstNode} node - Candidate identifier node.
|
|
157
|
+
* @returns {string} Validated identifier.
|
|
158
|
+
*/
|
|
159
|
+
identifier(node) {
|
|
160
|
+
const name = this.text(node);
|
|
161
|
+
if (node.type != "identifier" || !isZigIdentifier(name))
|
|
162
|
+
this.fail(node, "reserved or unsupported identifier");
|
|
163
|
+
return name;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Converts an exact source scalar annotation.
|
|
167
|
+
* @param {CstNode} node - Type node.
|
|
168
|
+
* @param {boolean} [allowVoid] - Whether void is valid here.
|
|
169
|
+
* @returns {import("../semantic/types.js").SemanticFunctionReturnType} Semantic type.
|
|
170
|
+
*/
|
|
171
|
+
type(node, allowVoid = false) {
|
|
172
|
+
const spelling = this.text(node);
|
|
173
|
+
if (allowVoid && node.type == "builtin_type" && spelling == "void") {
|
|
174
|
+
this.shape(node, ["void"]);
|
|
175
|
+
return withParserRanges({ kind: "TypeReference", name: "void" }, { type: this.location(node) });
|
|
176
|
+
}
|
|
177
|
+
if (node.type == "builtin_type" && ["i64", "bool"].includes(spelling)) {
|
|
178
|
+
if (spelling == "bool")
|
|
179
|
+
this.shape(node, ["bool"]);
|
|
180
|
+
else if (node.children.length)
|
|
181
|
+
this.fail(node, "scalar type shape");
|
|
182
|
+
}
|
|
183
|
+
else if (node.type == "slice_type" && spelling == "[]const u8") {
|
|
184
|
+
this.shape(node, ["[", "]", "const", this.parts(node)[3]]);
|
|
185
|
+
const child = this.parts(node)[3];
|
|
186
|
+
if (child.type != "builtin_type" || this.text(child) != "u8" || child.children.length)
|
|
187
|
+
this.fail(child, "immutable UTF-8 slice element");
|
|
188
|
+
}
|
|
189
|
+
else
|
|
190
|
+
return missingType("zig", allowVoid ? "function return" : "scalar", this.location(node));
|
|
191
|
+
const type = sourceScalarType("zig", spelling, this.location(node));
|
|
192
|
+
if (!type)
|
|
193
|
+
return missingType("zig", "scalar", this.location(node));
|
|
194
|
+
return type;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Decomposes an exact direct call.
|
|
198
|
+
* @param {CstNode} node - Call expression node.
|
|
199
|
+
* @returns {{name: CstNode, arguments: CstNode[]}} Callee and ordered arguments.
|
|
200
|
+
*/
|
|
201
|
+
call(node) {
|
|
202
|
+
if (node.type != "call_expression")
|
|
203
|
+
this.fail(node, "direct call required");
|
|
204
|
+
const name = this.field(node, "function");
|
|
205
|
+
const parts = this.parts(node);
|
|
206
|
+
const argumentsAndCommas = parts.slice(2, -1);
|
|
207
|
+
const args = argumentsAndCommas.filter((_part, index) => index % 2 == 0);
|
|
208
|
+
this.shape(node, [name, "(", ...args.flatMap((argument, index) => index ? [",", argument] : [argument]), ")"]);
|
|
209
|
+
return { name, arguments: args };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Decodes one bounded ordinary Zig string literal.
|
|
213
|
+
* @param {CstNode} node - String node.
|
|
214
|
+
* @returns {string} Unicode scalar value.
|
|
215
|
+
*/
|
|
216
|
+
string(node) {
|
|
217
|
+
if (node.type != "string")
|
|
218
|
+
this.fail(node, "ordinary UTF-8 string literal required");
|
|
219
|
+
const parts = this.parts(node);
|
|
220
|
+
this.shape(node, ['"', ...parts.slice(1, -1), '"']);
|
|
221
|
+
let value = "";
|
|
222
|
+
for (const part of parts.slice(1, -1)) {
|
|
223
|
+
const spelling = this.text(part);
|
|
224
|
+
if (part.type == "string_content") {
|
|
225
|
+
if (/[\r\n]/u.test(spelling))
|
|
226
|
+
this.fail(part, "raw string line terminator");
|
|
227
|
+
value += spelling;
|
|
228
|
+
}
|
|
229
|
+
else if (part.type == "escape_sequence") {
|
|
230
|
+
const simple = new Map([["\\n", "\n"], ["\\r", "\r"], ["\\t", "\t"], ["\\\\", "\\"], ['\\"', '"']]);
|
|
231
|
+
if (simple.has(spelling))
|
|
232
|
+
value += simple.get(spelling);
|
|
233
|
+
else if (/^\\x[0-9a-fA-F]{2}$/u.test(spelling)) {
|
|
234
|
+
const scalar = Number.parseInt(spelling.slice(2), 16);
|
|
235
|
+
if (scalar > 127)
|
|
236
|
+
this.fail(part, "non-ASCII byte escape");
|
|
237
|
+
value += String.fromCodePoint(scalar);
|
|
238
|
+
}
|
|
239
|
+
else if (/^\\u\{[0-9a-fA-F]{1,6}\}$/u.test(spelling)) {
|
|
240
|
+
const scalar = Number.parseInt(spelling.slice(3, -1), 16);
|
|
241
|
+
if (scalar > 0x10FFFF || scalar >= 0xD800 && scalar <= 0xDFFF)
|
|
242
|
+
this.fail(part, "non-scalar Unicode escape");
|
|
243
|
+
value += String.fromCodePoint(scalar);
|
|
244
|
+
}
|
|
245
|
+
else
|
|
246
|
+
this.fail(part, "unsupported string escape");
|
|
247
|
+
}
|
|
248
|
+
else
|
|
249
|
+
this.fail(part, "string child");
|
|
250
|
+
}
|
|
251
|
+
if (!hasOnlyUnicodeScalars(value))
|
|
252
|
+
this.fail(node, "non-scalar string value");
|
|
253
|
+
return value;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Converts one supported scalar expression.
|
|
257
|
+
* @param {CstNode} node - Expression node.
|
|
258
|
+
* @returns {Expression} Semantic expression.
|
|
259
|
+
*/
|
|
260
|
+
expression(node) {
|
|
261
|
+
const location = this.location(node);
|
|
262
|
+
if (node.type == "parenthesized_expression") {
|
|
263
|
+
const parts = this.parts(node);
|
|
264
|
+
this.shape(node, ["(", parts[1], ")"]);
|
|
265
|
+
return this.expression(parts[1]);
|
|
266
|
+
}
|
|
267
|
+
if (node.type == "identifier") {
|
|
268
|
+
const temporary = this.temporaryExpressions?.get(this.text(node));
|
|
269
|
+
if (temporary) {
|
|
270
|
+
this.temporaryExpressions?.delete(this.text(node));
|
|
271
|
+
return temporary;
|
|
272
|
+
}
|
|
273
|
+
return withParserRanges({ kind: "IdentifierExpression", location, name: this.identifier(node) }, { name: location });
|
|
274
|
+
}
|
|
275
|
+
if (node.type == "integer") {
|
|
276
|
+
const spelling = this.text(node);
|
|
277
|
+
const value = Number(spelling);
|
|
278
|
+
if (!/^(?:0|[1-9][0-9]*)$/u.test(spelling) || !Number.isSafeInteger(value))
|
|
279
|
+
this.fail(node, "non-safe or noncanonical i64 literal");
|
|
280
|
+
return withParserRanges({ kind: "IntegerLiteral", location, value }, { literal: location });
|
|
281
|
+
}
|
|
282
|
+
if (node.type == "boolean") {
|
|
283
|
+
const spelling = this.text(node);
|
|
284
|
+
if (spelling != "true" && spelling != "false")
|
|
285
|
+
this.fail(node, "Boolean literal spelling");
|
|
286
|
+
this.shape(node, [spelling]);
|
|
287
|
+
return withParserRanges({ kind: "BooleanLiteral", location, value: spelling == "true" }, { literal: location });
|
|
288
|
+
}
|
|
289
|
+
if (node.type == "string")
|
|
290
|
+
return withParserRanges({ kind: "StringLiteral", location, value: this.string(node) }, { literal: location });
|
|
291
|
+
if (node.type == "unary_expression" || node.type == "error_union_type") {
|
|
292
|
+
const parts = this.parts(node);
|
|
293
|
+
const operator = node.type == "unary_expression" ? this.field(node, "operator") : parts[0];
|
|
294
|
+
const operand = node.type == "unary_expression" ? this.field(node, "argument") : this.field(node, "ok");
|
|
295
|
+
this.shape(node, [operator, operand]);
|
|
296
|
+
if (operator.type != "-" && operator.type != "!")
|
|
297
|
+
this.fail(operator, "unary operator");
|
|
298
|
+
return this.unary(node, operator.type == "-" ? "Negate" : "Not", this.expression(operand), operator);
|
|
299
|
+
}
|
|
300
|
+
if (node.type == "binary_expression") {
|
|
301
|
+
const left = this.field(node, "left");
|
|
302
|
+
const right = this.field(node, "right");
|
|
303
|
+
const operator = this.field(node, "operator");
|
|
304
|
+
const intent = binaryOperations.get(operator.type);
|
|
305
|
+
this.shape(node, [left, operator, right]);
|
|
306
|
+
if (!intent)
|
|
307
|
+
this.fail(operator, "unsupported binary operator");
|
|
308
|
+
return this.binary(node, intent, this.expression(left), this.expression(right), operator);
|
|
309
|
+
}
|
|
310
|
+
if (node.type == "call_expression") {
|
|
311
|
+
const call = this.call(node);
|
|
312
|
+
if (call.name.type != "identifier")
|
|
313
|
+
this.fail(call.name, "direct function call required");
|
|
314
|
+
const name = this.text(call.name);
|
|
315
|
+
if (name == "semantifold_integer_negate") {
|
|
316
|
+
if (call.arguments.length != 1)
|
|
317
|
+
this.fail(node, "negation helper arity");
|
|
318
|
+
return this.unary(node, "Negate", this.expression(call.arguments[0]), call.name);
|
|
319
|
+
}
|
|
320
|
+
const intent = helperOperations.get(name);
|
|
321
|
+
if (intent) {
|
|
322
|
+
if (call.arguments.length != 2)
|
|
323
|
+
this.fail(node, "operator helper arity");
|
|
324
|
+
return this.binary(node, intent, this.expression(call.arguments[0]), this.expression(call.arguments[1]), call.name);
|
|
325
|
+
}
|
|
326
|
+
if (name.startsWith("semantifold_"))
|
|
327
|
+
this.fail(call.name, "support helper outside its exact semantic role");
|
|
328
|
+
const callee = this.identifier(call.name);
|
|
329
|
+
return withParserRanges({ kind: "CallExpression", location, callee, arguments: call.arguments.map(argument => this.expression(argument)) }, { callee: this.location(call.name) });
|
|
330
|
+
}
|
|
331
|
+
return this.fail(node);
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Adapts one typed binary operator.
|
|
335
|
+
* @param {CstNode} node - Whole expression node.
|
|
336
|
+
* @param {string} intent - Shared operator intent.
|
|
337
|
+
* @param {Expression} left - Left operand.
|
|
338
|
+
* @param {Expression} right - Right operand.
|
|
339
|
+
* @param {CstNode} operator - Source operator occurrence.
|
|
340
|
+
* @returns {Expression} Adapted semantic expression.
|
|
341
|
+
*/
|
|
342
|
+
binary(node, intent, left, right, operator) {
|
|
343
|
+
const expression = /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "BinaryExpression", location: this.location(node), left, right }, { operator: this.location(operator) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (intent)));
|
|
344
|
+
this.operations.set(expression, { node: operator, spelling: this.text(operator) });
|
|
345
|
+
return expression;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Adapts one typed unary operator.
|
|
349
|
+
* @param {CstNode} node - Whole expression node.
|
|
350
|
+
* @param {"Negate" | "Not"} intent - Shared operator intent.
|
|
351
|
+
* @param {Expression} operand - Converted operand.
|
|
352
|
+
* @param {CstNode} operator - Source operator occurrence.
|
|
353
|
+
* @returns {Expression} Adapted semantic expression.
|
|
354
|
+
*/
|
|
355
|
+
unary(node, intent, operand, operator) {
|
|
356
|
+
const expression = /** @type {Expression} */ (withAdaptedOperation(withParserRanges({ kind: "UnaryExpression", location: this.location(node), operand }, { operator: this.location(operator) }), intent));
|
|
357
|
+
this.operations.set(expression, { node: operator, spelling: this.text(operator) });
|
|
358
|
+
return expression;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Converts one supported statement.
|
|
362
|
+
* @param {CstNode} node - Statement node.
|
|
363
|
+
* @returns {Statement} Semantic statement.
|
|
364
|
+
*/
|
|
365
|
+
statement(node) {
|
|
366
|
+
const location = this.location(node);
|
|
367
|
+
const parts = this.parts(node);
|
|
368
|
+
if (node.type == "variable_declaration") {
|
|
369
|
+
if (["const", "var"].includes(parts[0]?.type)) {
|
|
370
|
+
const typeNode = node.children.find(({ field }) => field == "type")?.node;
|
|
371
|
+
if (!typeNode)
|
|
372
|
+
return missingType("zig", "local", location);
|
|
373
|
+
const name = parts[1];
|
|
374
|
+
const value = parts[5];
|
|
375
|
+
this.shape(node, [parts[0], name, ":", typeNode, "=", value, ";"]);
|
|
376
|
+
return withParserRanges({ kind: "LocalDeclaration", location, name: this.identifier(name), type: /** @type {import("../semantic/types.js").TypeReference} */ (this.type(typeNode)), mutable: parts[0].type == "var",
|
|
377
|
+
initializer: this.expression(value) }, { name: this.location(name), operator: this.location(parts[4]) });
|
|
378
|
+
}
|
|
379
|
+
const targetNode = parts[0];
|
|
380
|
+
const value = parts[2];
|
|
381
|
+
this.shape(node, [targetNode, "=", value, ";"]);
|
|
382
|
+
const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: this.location(targetNode), name: this.identifier(targetNode) }, { name: this.location(targetNode) });
|
|
383
|
+
return withParserRanges({ kind: "AssignmentStatement", location, target, expression: this.expression(value) }, { operator: this.location(parts[1]) });
|
|
384
|
+
}
|
|
385
|
+
if (node.type == "if_statement")
|
|
386
|
+
return this.conditional(node);
|
|
387
|
+
if (node.type != "expression_statement")
|
|
388
|
+
this.fail(node, "explicit statement required");
|
|
389
|
+
const expression = parts[0];
|
|
390
|
+
this.shape(node, [expression, ";"]);
|
|
391
|
+
if (expression.type == "return_expression") {
|
|
392
|
+
const returned = this.parts(expression);
|
|
393
|
+
if (returned.length == 1) {
|
|
394
|
+
this.shape(expression, ["return"]);
|
|
395
|
+
return { kind: "ReturnStatement", location };
|
|
396
|
+
}
|
|
397
|
+
this.shape(expression, ["return", returned[1]]);
|
|
398
|
+
return { kind: "ReturnStatement", location, expression: this.expression(returned[1]) };
|
|
399
|
+
}
|
|
400
|
+
if (expression.type != "call_expression")
|
|
401
|
+
this.fail(expression, "direct void call statement required");
|
|
402
|
+
const call = this.call(expression);
|
|
403
|
+
const name = this.text(call.name);
|
|
404
|
+
if (/^semantifold_print_(?:integer|boolean|string)$/u.test(name)) {
|
|
405
|
+
if (call.name.type != "identifier" || call.arguments.length != 1)
|
|
406
|
+
this.fail(expression, "exact print helper call required");
|
|
407
|
+
const statement = { kind: /** @type {const} */ ("PrintStatement"), location, expression: this.expression(call.arguments[0]) };
|
|
408
|
+
this.prints.set(statement, { node: call.name, type: name.slice("semantifold_print_".length) });
|
|
409
|
+
return statement;
|
|
410
|
+
}
|
|
411
|
+
const value = this.expression(expression);
|
|
412
|
+
if (value.kind != "CallExpression")
|
|
413
|
+
this.fail(expression, "direct void call statement required");
|
|
414
|
+
return { kind: "ExpressionStatement", location, expression: value };
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Converts one strict Boolean conditional.
|
|
418
|
+
* @param {CstNode} node - If-statement node.
|
|
419
|
+
* @returns {import("../semantic/types.js").IfStatement} Semantic conditional.
|
|
420
|
+
*/
|
|
421
|
+
conditional(node) {
|
|
422
|
+
const condition = this.field(node, "condition");
|
|
423
|
+
const body = this.field(node, "body");
|
|
424
|
+
const alternative = this.parts(node).find(child => child.type == "else_clause");
|
|
425
|
+
this.shape(node, ["if", "(", condition, ")", body, ...(alternative ? [alternative] : [])]);
|
|
426
|
+
const statement = { kind: /** @type {const} */ ("IfStatement"), location: this.location(node), condition: this.expression(condition), consequent: this.blockExpression(body) };
|
|
427
|
+
if (!alternative)
|
|
428
|
+
return statement;
|
|
429
|
+
const branch = this.field(alternative, "alternative");
|
|
430
|
+
this.shape(alternative, ["else", branch]);
|
|
431
|
+
if (branch.type != "labeled_statement")
|
|
432
|
+
this.fail(branch, "braced else block required");
|
|
433
|
+
const block = this.parts(branch)[0];
|
|
434
|
+
this.shape(branch, [block]);
|
|
435
|
+
return { ...statement, alternate: this.block(block) };
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Unwraps one braced conditional block expression.
|
|
439
|
+
* @param {CstNode} node - Block-expression node.
|
|
440
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
441
|
+
*/
|
|
442
|
+
blockExpression(node) {
|
|
443
|
+
if (node.type != "block_expression")
|
|
444
|
+
this.fail(node, "braced conditional block required");
|
|
445
|
+
const block = this.parts(node)[0];
|
|
446
|
+
this.shape(node, [block]);
|
|
447
|
+
return this.block(block);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Converts one lexical block while consuming exact compiler scaffolds.
|
|
451
|
+
* @param {CstNode} node - Block node.
|
|
452
|
+
* @param {number} [skip] - Fixed leading generated statements to omit.
|
|
453
|
+
* @param {import("../semantic/types.js").Parameter[]} [parameters] - Parameters requiring scaffold checks.
|
|
454
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
455
|
+
*/
|
|
456
|
+
block(node, skip = 0, parameters = []) {
|
|
457
|
+
if (node.type != "block")
|
|
458
|
+
this.fail(node, "braced block required");
|
|
459
|
+
const parts = this.parts(node);
|
|
460
|
+
this.shape(node, ["{", ...parts.slice(1, -1), "}"]);
|
|
461
|
+
const sourceStatements = this.significant(node).slice(1 + skip, -1);
|
|
462
|
+
return { kind: "Block", location: this.location(node), statements: this.generated
|
|
463
|
+
? this.generatedStatements(sourceStatements, parameters)
|
|
464
|
+
: this.directStatements(sourceStatements, parameters) };
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Converts the legacy direct statement shape when diagnosing a missing generated marker.
|
|
468
|
+
* @param {CstNode[]} sourceStatements - Ordered direct children.
|
|
469
|
+
* @param {import("../semantic/types.js").Parameter[]} parameters - Function parameters.
|
|
470
|
+
* @returns {Statement[]} Semantic statements.
|
|
471
|
+
*/
|
|
472
|
+
directStatements(sourceStatements, parameters) {
|
|
473
|
+
let cursor = 0;
|
|
474
|
+
for (const parameter of parameters) {
|
|
475
|
+
const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], parameter.name) : undefined;
|
|
476
|
+
this.scaffolds.set(parameter, kind ?? "none");
|
|
477
|
+
if (kind)
|
|
478
|
+
cursor += 1;
|
|
479
|
+
}
|
|
480
|
+
/** @type {Statement[]} */
|
|
481
|
+
const statements = [];
|
|
482
|
+
while (cursor < sourceStatements.length) {
|
|
483
|
+
const statement = this.statement(sourceStatements[cursor]);
|
|
484
|
+
statements.push(statement);
|
|
485
|
+
cursor += 1;
|
|
486
|
+
if (statement.kind == "LocalDeclaration") {
|
|
487
|
+
const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], statement.name) : undefined;
|
|
488
|
+
this.scaffolds.set(statement, kind ?? "none");
|
|
489
|
+
if (kind)
|
|
490
|
+
cursor += 1;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return statements;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Reconstructs complete generated statement regions before canonical whole-CST verification.
|
|
497
|
+
* @param {CstNode[]} sourceStatements - Significant direct block children.
|
|
498
|
+
* @param {import("../semantic/types.js").Parameter[]} parameters - Function parameters.
|
|
499
|
+
* @returns {Statement[]} Reconstructed semantic statements.
|
|
500
|
+
*/
|
|
501
|
+
generatedStatements(sourceStatements, parameters) {
|
|
502
|
+
/** @type {Statement[]} */
|
|
503
|
+
const statements = [];
|
|
504
|
+
let cursor = 0;
|
|
505
|
+
for (const parameter of parameters) {
|
|
506
|
+
const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], parameter.name) : undefined;
|
|
507
|
+
this.scaffolds.set(parameter, kind ?? "none");
|
|
508
|
+
if (kind)
|
|
509
|
+
cursor += 1;
|
|
510
|
+
}
|
|
511
|
+
while (cursor < sourceStatements.length) {
|
|
512
|
+
const begin = sourceStatements[cursor++];
|
|
513
|
+
const match = begin.type == "comment" &&
|
|
514
|
+
/^\/\/ semantifold:ordered-expression:zig:v1 begin ([0-9]{6}) ([0-9a-f]{64})$/u.exec(this.marker(begin));
|
|
515
|
+
if (!match)
|
|
516
|
+
this.fail(begin, "complete generated ordered statement region required");
|
|
517
|
+
const outerExpressions = this.temporaryExpressions;
|
|
518
|
+
const outerNames = this.temporaryNames;
|
|
519
|
+
this.temporaryExpressions = new Map();
|
|
520
|
+
this.temporaryNames = new Set();
|
|
521
|
+
while (cursor < sourceStatements.length && this.temporaryDeclaration(sourceStatements[cursor])) {
|
|
522
|
+
cursor = this.readTemporary(sourceStatements, cursor);
|
|
523
|
+
}
|
|
524
|
+
const consumer = sourceStatements[cursor++];
|
|
525
|
+
if (!consumer)
|
|
526
|
+
this.fail(begin, "missing generated ordered consumer");
|
|
527
|
+
const statement = this.statement(consumer);
|
|
528
|
+
if (this.temporaryExpressions.size != 0)
|
|
529
|
+
this.fail(consumer, "unconsumed generated ordered temporary");
|
|
530
|
+
if (statement.kind == "LocalDeclaration") {
|
|
531
|
+
const kind = sourceStatements[cursor] ? this.useScaffold(sourceStatements[cursor], statement.name) : undefined;
|
|
532
|
+
this.scaffolds.set(statement, kind ?? "none");
|
|
533
|
+
if (kind)
|
|
534
|
+
cursor += 1;
|
|
535
|
+
}
|
|
536
|
+
const end = sourceStatements[cursor++];
|
|
537
|
+
if (!end || end.type != "comment" || this.marker(end) !=
|
|
538
|
+
`// semantifold:ordered-expression:zig:v1 end ${match[1]} ${match[2]}`)
|
|
539
|
+
this.fail(end ?? begin, "generated ordered marker pair");
|
|
540
|
+
this.temporaryExpressions = outerExpressions;
|
|
541
|
+
this.temporaryNames = outerNames;
|
|
542
|
+
statements.push(statement);
|
|
543
|
+
}
|
|
544
|
+
return statements;
|
|
545
|
+
}
|
|
546
|
+
/**
|
|
547
|
+
* Identifies a reserved ordered temporary declaration at the current region level.
|
|
548
|
+
* @param {CstNode} node - Candidate direct child.
|
|
549
|
+
* @returns {boolean} Whether it declares a reserved ordered temporary.
|
|
550
|
+
*/
|
|
551
|
+
temporaryDeclaration(node) {
|
|
552
|
+
const parts = this.parts(node);
|
|
553
|
+
return node.type == "variable_declaration" && ["const", "var"].includes(parts[0]?.type) &&
|
|
554
|
+
parts[1]?.type == "identifier" && this.text(parts[1]).startsWith("semantifold_ordered_");
|
|
555
|
+
}
|
|
556
|
+
/**
|
|
557
|
+
* Expands one typed ordered temporary and an optional conditional Boolean RHS.
|
|
558
|
+
* @param {CstNode[]} nodes - Current region children.
|
|
559
|
+
* @param {number} cursor - Temporary declaration position.
|
|
560
|
+
* @returns {number} Next unconsumed position.
|
|
561
|
+
*/
|
|
562
|
+
readTemporary(nodes, cursor) {
|
|
563
|
+
const node = nodes[cursor++];
|
|
564
|
+
const parts = this.parts(node);
|
|
565
|
+
const nameNode = parts[1];
|
|
566
|
+
const name = this.text(nameNode);
|
|
567
|
+
const typeNode = this.field(node, "type");
|
|
568
|
+
const value = parts[5];
|
|
569
|
+
this.shape(node, [parts[0], nameNode, ":", typeNode, "=", value, ";"]);
|
|
570
|
+
this.type(typeNode);
|
|
571
|
+
if (!/^semantifold_ordered_[0-9]{6}$/u.test(name) || this.temporaryNames?.has(name)) {
|
|
572
|
+
this.fail(nameNode, "generated ordered temporary declaration");
|
|
573
|
+
}
|
|
574
|
+
this.temporaryNames?.add(name);
|
|
575
|
+
let expression = this.expression(value);
|
|
576
|
+
const branch = nodes[cursor];
|
|
577
|
+
if (branch && this.shortCircuitBranch(branch, name)) {
|
|
578
|
+
const condition = this.field(branch, "condition");
|
|
579
|
+
const body = this.field(branch, "body");
|
|
580
|
+
const conditionParts = this.parts(condition);
|
|
581
|
+
const isOr = conditionParts[0]?.type == "!";
|
|
582
|
+
const target = isOr ? this.field(condition, condition.type == "unary_expression" ? "argument" : "ok") : condition;
|
|
583
|
+
this.shape(branch, ["if", "(", condition, ")", body]);
|
|
584
|
+
if (target.type != "identifier" || this.text(target) != name)
|
|
585
|
+
this.fail(target, "generated short-circuit temporary test");
|
|
586
|
+
if (isOr)
|
|
587
|
+
this.shape(condition, [conditionParts[0], target]);
|
|
588
|
+
if (isOr && conditionParts[0]?.type != "!")
|
|
589
|
+
this.fail(conditionParts[0] ?? condition, "generated short-circuit negation");
|
|
590
|
+
if (body.type != "block_expression")
|
|
591
|
+
this.fail(body, "generated short-circuit block");
|
|
592
|
+
const block = this.parts(body)[0];
|
|
593
|
+
this.shape(body, [block]);
|
|
594
|
+
if (block.type != "block")
|
|
595
|
+
this.fail(block, "generated short-circuit block");
|
|
596
|
+
const inside = this.significant(block).slice(1, -1);
|
|
597
|
+
let offset = 0;
|
|
598
|
+
while (offset < inside.length && this.temporaryDeclaration(inside[offset]))
|
|
599
|
+
offset = this.readTemporary(inside, offset);
|
|
600
|
+
if (offset != inside.length - 1)
|
|
601
|
+
this.fail(block, "generated short-circuit final assignment");
|
|
602
|
+
const assignment = inside[offset];
|
|
603
|
+
const assignmentParts = this.parts(assignment);
|
|
604
|
+
const left = assignmentParts[0];
|
|
605
|
+
const right = assignmentParts[2];
|
|
606
|
+
this.shape(assignment, [left, "=", right, ";"]);
|
|
607
|
+
if (left.type != "identifier" || this.text(left) != name)
|
|
608
|
+
this.fail(left, "generated short-circuit result write");
|
|
609
|
+
if (right.type != "binary_expression")
|
|
610
|
+
this.fail(right, "generated short-circuit result expression");
|
|
611
|
+
const repeated = this.field(right, "left");
|
|
612
|
+
const operand = this.field(right, "right");
|
|
613
|
+
const operator = this.field(right, "operator");
|
|
614
|
+
const spelling = isOr ? "or" : "and";
|
|
615
|
+
this.shape(right, [repeated, spelling, operand]);
|
|
616
|
+
if (repeated.type != "identifier" || this.text(repeated) != name)
|
|
617
|
+
this.fail(repeated, "generated short-circuit consumed value");
|
|
618
|
+
expression = this.binary(right, isOr ? "Or" : "And", expression, this.expression(operand), operator);
|
|
619
|
+
cursor += 1;
|
|
620
|
+
}
|
|
621
|
+
this.temporaryExpressions?.set(name, expression);
|
|
622
|
+
return cursor;
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Distinguishes an internal conditional RHS from the following semantic `if` consumer using only direct CST structure.
|
|
626
|
+
* @param {CstNode} node - Candidate conditional.
|
|
627
|
+
* @param {string} name - Ordered Boolean result name.
|
|
628
|
+
* @returns {boolean} Whether the node has the complete outer shape of a short-circuit update.
|
|
629
|
+
*/
|
|
630
|
+
shortCircuitBranch(node, name) {
|
|
631
|
+
if (node.type != "if_statement" || this.parts(node).some(child => child.type == "else_clause"))
|
|
632
|
+
return false;
|
|
633
|
+
const body = node.children.find(({ field }) => field == "body")?.node;
|
|
634
|
+
if (body?.type != "block_expression")
|
|
635
|
+
return false;
|
|
636
|
+
const block = this.parts(body)[0];
|
|
637
|
+
if (block?.type != "block")
|
|
638
|
+
return false;
|
|
639
|
+
const inside = this.significant(block).slice(1, -1);
|
|
640
|
+
const final = inside.at(-1);
|
|
641
|
+
const finalParts = final ? this.parts(final) : [];
|
|
642
|
+
return inside.length > 0 && !inside.some(child => child.type == "comment") && final?.type == "variable_declaration" &&
|
|
643
|
+
finalParts[0]?.type == "identifier" && this.text(finalParts[0]) == name && finalParts[1]?.type == "=";
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Recognizes one exact generated unused or unmutated binding scaffold.
|
|
647
|
+
* @param {CstNode} node - Candidate statement node.
|
|
648
|
+
* @param {string} name - Binding name.
|
|
649
|
+
* @returns {"use" | "address" | undefined} Scaffold form when matched.
|
|
650
|
+
*/
|
|
651
|
+
useScaffold(node, name) {
|
|
652
|
+
const parts = this.parts(node);
|
|
653
|
+
if (node.type != "variable_declaration" || parts.length != 4 || parts[0].type != "identifier" || this.text(parts[0]) != "_" || parts[1].type != "=" || parts[3].type != ";")
|
|
654
|
+
return undefined;
|
|
655
|
+
if (parts[2].type == "identifier" && this.text(parts[2]) == name)
|
|
656
|
+
return "use";
|
|
657
|
+
if (parts[2].type == "reference_expression") {
|
|
658
|
+
const reference = this.parts(parts[2]);
|
|
659
|
+
if (reference.length == 2 && reference[0].type == "&" && reference[1].type == "identifier" && this.text(reference[1]) == name)
|
|
660
|
+
return "address";
|
|
661
|
+
}
|
|
662
|
+
return undefined;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* Converts one canonical top-level semantic function.
|
|
666
|
+
* @param {CstNode} node - Function declaration node.
|
|
667
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
668
|
+
*/
|
|
669
|
+
function(node) {
|
|
670
|
+
const name = this.field(node, "name");
|
|
671
|
+
const parameters = this.parts(node).find(child => child.type == "parameters");
|
|
672
|
+
const returnType = this.field(node, "type");
|
|
673
|
+
const body = this.field(node, "body");
|
|
674
|
+
if (!parameters)
|
|
675
|
+
this.fail(node, "parameter list required");
|
|
676
|
+
this.shape(node, ["fn", name, parameters, returnType, body]);
|
|
677
|
+
const parameterParts = this.parts(parameters);
|
|
678
|
+
const declarations = parameterParts.slice(1, -1).filter((_part, index) => index % 2 == 0);
|
|
679
|
+
this.shape(parameters, ["(", ...declarations.flatMap((parameter, index) => index ? [",", parameter] : [parameter]), ")"]);
|
|
680
|
+
const converted = declarations.map(parameter => {
|
|
681
|
+
if (parameter.type != "parameter")
|
|
682
|
+
this.fail(parameter, "required typed parameter");
|
|
683
|
+
const parameterName = this.field(parameter, "name");
|
|
684
|
+
const type = this.field(parameter, "type");
|
|
685
|
+
this.shape(parameter, [parameterName, ":", type]);
|
|
686
|
+
return withParserRanges({ kind: /** @type {const} */ ("Parameter"), location: this.location(parameter), name: this.identifier(parameterName), type: /** @type {import("../semantic/types.js").TypeReference} */ (this.type(type)) }, { name: this.location(parameterName) });
|
|
687
|
+
});
|
|
688
|
+
return withParserRanges({ kind: "FunctionDeclaration", location: this.location(node), name: this.identifier(name), parameters: converted,
|
|
689
|
+
returnType: this.type(returnType, true), body: this.block(body, 0, converted) }, { name: this.location(name) });
|
|
690
|
+
}
|
|
691
|
+
/**
|
|
692
|
+
* Compares every node, token, and field against canonical generated support.
|
|
693
|
+
* @param {CstNode} actual - Source subtree.
|
|
694
|
+
* @param {CstNode} expected - Canonical subtree.
|
|
695
|
+
* @param {ZigReader} canonical - Reader owning the canonical source.
|
|
696
|
+
*/
|
|
697
|
+
compareTree(actual, expected, canonical) {
|
|
698
|
+
if (actual.type != expected.type || actual.named != expected.named || actual.extra != expected.extra)
|
|
699
|
+
this.fail(actual, "modified Zig support node");
|
|
700
|
+
const left = this.significant(actual);
|
|
701
|
+
const right = canonical.significant(expected);
|
|
702
|
+
if (left.length != right.length)
|
|
703
|
+
this.fail(actual, "modified Zig support children");
|
|
704
|
+
if (!left.length) {
|
|
705
|
+
const actualText = actual.type == "comment" && /semantifold:/u.test(this.text(actual)) ? this.marker(actual) : this.text(actual);
|
|
706
|
+
const expectedText = expected.type == "comment" && /semantifold:/u.test(canonical.text(expected)) ? canonical.marker(expected) : canonical.text(expected);
|
|
707
|
+
if (actualText != expectedText)
|
|
708
|
+
this.fail(actual, "modified Zig support token");
|
|
709
|
+
}
|
|
710
|
+
left.forEach((child, index) => {
|
|
711
|
+
const expectedChild = right[index];
|
|
712
|
+
if (!expectedChild || actual.children.find(edge => edge.node === child)?.field != expected.children.find(edge => edge.node === expectedChild)?.field) {
|
|
713
|
+
this.fail(child, "modified Zig support field");
|
|
714
|
+
}
|
|
715
|
+
this.compareTree(child, expectedChild, canonical);
|
|
716
|
+
});
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Resolves a validated expression's scalar result.
|
|
720
|
+
* @param {Expression} expression - Semantic expression.
|
|
721
|
+
* @param {Map<string, Scalar>} bindings - Visible binding types.
|
|
722
|
+
* @returns {Scalar} Scalar result name.
|
|
723
|
+
*/
|
|
724
|
+
expressionType(expression, bindings) {
|
|
725
|
+
if (expression.kind == "StringLiteral")
|
|
726
|
+
return "string";
|
|
727
|
+
if (expression.kind == "IntegerLiteral")
|
|
728
|
+
return "integer";
|
|
729
|
+
if (expression.kind == "BooleanLiteral")
|
|
730
|
+
return "boolean";
|
|
731
|
+
if (expression.kind == "BinaryExpression" || expression.kind == "UnaryExpression")
|
|
732
|
+
return expression.type;
|
|
733
|
+
if (expression.kind != "CallExpression" && expression.kind != "IdentifierExpression")
|
|
734
|
+
throw new Error("Validated Zig source exposed a collection expression.");
|
|
735
|
+
const type = expression.kind == "CallExpression" ? this.functions.get(expression.callee) : bindings.get(expression.name);
|
|
736
|
+
if (!type)
|
|
737
|
+
throw new Error("Validated Zig expression lost its scalar binding.");
|
|
738
|
+
return type;
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Requires each typed operation to retain the one exact Zig operator/helper spelling that implements it.
|
|
742
|
+
* @param {Expression} expression - Resolved scalar expression.
|
|
743
|
+
*/
|
|
744
|
+
validateOperationExpression(expression) {
|
|
745
|
+
if (expression.kind == "CallExpression") {
|
|
746
|
+
expression.arguments.forEach(argument => this.validateOperationExpression(argument));
|
|
747
|
+
return;
|
|
748
|
+
}
|
|
749
|
+
if (expression.kind == "UnaryExpression") {
|
|
750
|
+
const identity = this.operations.get(expression);
|
|
751
|
+
const expected = operationSpellings.get(expression.operation);
|
|
752
|
+
if (!identity)
|
|
753
|
+
throw new Error("Resolved Zig unary operation lost its parser identity.");
|
|
754
|
+
if (identity.spelling != expected)
|
|
755
|
+
this.fail(identity.node, `exact ${expression.operation} Zig operator/helper required`);
|
|
756
|
+
this.validateOperationExpression(expression.operand);
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
if (expression.kind == "BinaryExpression") {
|
|
760
|
+
const identity = this.operations.get(expression);
|
|
761
|
+
const expected = operationSpellings.get(expression.operation);
|
|
762
|
+
if (!identity)
|
|
763
|
+
throw new Error("Resolved Zig binary operation lost its parser identity.");
|
|
764
|
+
if (identity.spelling != expected)
|
|
765
|
+
this.fail(identity.node, `exact ${expression.operation} Zig operator/helper required`);
|
|
766
|
+
this.validateOperationExpression(expression.left);
|
|
767
|
+
this.validateOperationExpression(expression.right);
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
/**
|
|
771
|
+
* Validates operation identity throughout one lexical block.
|
|
772
|
+
* @param {import("../semantic/types.js").Block} block - Block whose expressions must retain exact Zig identity.
|
|
773
|
+
*/
|
|
774
|
+
validateOperations(block) {
|
|
775
|
+
for (const statement of block.statements) {
|
|
776
|
+
if (statement.kind == "LocalDeclaration")
|
|
777
|
+
this.validateOperationExpression(statement.initializer);
|
|
778
|
+
else if (statement.kind == "AssignmentStatement" || statement.kind == "ExpressionStatement" || statement.kind == "PrintStatement") {
|
|
779
|
+
this.validateOperationExpression(statement.expression);
|
|
780
|
+
}
|
|
781
|
+
else if (statement.kind == "ReturnStatement") {
|
|
782
|
+
if (statement.expression)
|
|
783
|
+
this.validateOperationExpression(statement.expression);
|
|
784
|
+
}
|
|
785
|
+
else if (statement.kind == "IfStatement") {
|
|
786
|
+
this.validateOperationExpression(statement.condition);
|
|
787
|
+
this.validateOperations(statement.consequent);
|
|
788
|
+
if (statement.alternate)
|
|
789
|
+
this.validateOperations(statement.alternate);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* Confirms each generated output helper matches its semantic operand.
|
|
795
|
+
* @param {import("../semantic/types.js").Block} block - Block to inspect.
|
|
796
|
+
* @param {Map<string, Scalar>} inherited - Visible binding types.
|
|
797
|
+
*/
|
|
798
|
+
validatePrints(block, inherited) {
|
|
799
|
+
const bindings = new Map(inherited);
|
|
800
|
+
for (const statement of block.statements) {
|
|
801
|
+
if (statement.kind == "LocalDeclaration") {
|
|
802
|
+
bindings.set(statement.name, /** @type {import("../semantic/types.js").TypeReference} */ (statement.type).name);
|
|
803
|
+
}
|
|
804
|
+
else if (statement.kind == "PrintStatement") {
|
|
805
|
+
const print = this.prints.get(statement);
|
|
806
|
+
if (!print || this.expressionType(statement.expression, bindings) != print.type)
|
|
807
|
+
this.fail(print?.node ?? /** @type {CstNode} */ ({}), "print helper scalar mismatch");
|
|
808
|
+
}
|
|
809
|
+
else if (statement.kind == "IfStatement") {
|
|
810
|
+
this.validatePrints(statement.consequent, bindings);
|
|
811
|
+
if (statement.alternate)
|
|
812
|
+
this.validatePrints(statement.alternate, bindings);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
/**
|
|
817
|
+
* Confirms all and only compiler-required binding scaffolds are present.
|
|
818
|
+
* @param {import("../semantic/types.js").FunctionDeclaration | import("../semantic/types.js").EntryPoint} owner - Function or entry owner.
|
|
819
|
+
*/
|
|
820
|
+
validateScaffolds(owner) {
|
|
821
|
+
const usage = collectZigBindingUsage(owner.body);
|
|
822
|
+
const parameters = owner.kind == "FunctionDeclaration" ? owner.parameters : [];
|
|
823
|
+
for (const parameter of parameters) {
|
|
824
|
+
const expected = usage.reads.has(parameter.name) ? "none" : "use";
|
|
825
|
+
if (this.scaffolds.get(parameter) != expected)
|
|
826
|
+
unsupportedSyntax("zig", `incorrect unused-parameter scaffold for '${parameter.name}'`, parameter.location);
|
|
827
|
+
}
|
|
828
|
+
/**
|
|
829
|
+
* Checks local scaffolds recursively.
|
|
830
|
+
* @param {import("../semantic/types.js").Block} block - Block to inspect.
|
|
831
|
+
*/
|
|
832
|
+
const visit = (block) => {
|
|
833
|
+
for (const statement of block.statements) {
|
|
834
|
+
if (statement.kind == "LocalDeclaration") {
|
|
835
|
+
const expected = statement.mutable && !usage.writes.has(statement.name) ? "address" :
|
|
836
|
+
!statement.mutable && !usage.reads.has(statement.name) ? "use" : "none";
|
|
837
|
+
if (this.scaffolds.get(statement) != expected)
|
|
838
|
+
unsupportedSyntax("zig", `incorrect local binding scaffold for '${statement.name}'`, statement.location);
|
|
839
|
+
}
|
|
840
|
+
else if (statement.kind == "IfStatement") {
|
|
841
|
+
visit(statement.consequent);
|
|
842
|
+
if (statement.alternate)
|
|
843
|
+
visit(statement.alternate);
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
};
|
|
847
|
+
visit(owner.body);
|
|
848
|
+
}
|
|
849
|
+
/**
|
|
850
|
+
* Converts a complete canonical Zig project entry.
|
|
851
|
+
* @param {CstNode} root - Source-file root.
|
|
852
|
+
* @returns {import("../semantic/types.js").SemanticModule} Validated semantic module.
|
|
853
|
+
*/
|
|
854
|
+
module(root) {
|
|
855
|
+
this.validateTree(root);
|
|
856
|
+
if (root.type != "source_file")
|
|
857
|
+
this.fail(root, "Zig source root required");
|
|
858
|
+
const canonical = new ZigReader(this.filename, zigRuntime);
|
|
859
|
+
const support = canonical.significant(parseZigCst(zigRuntime).root);
|
|
860
|
+
const nodes = this.significant(root);
|
|
861
|
+
if (nodes.length < support.length + 2)
|
|
862
|
+
this.fail(root, "complete Zig runtime, ordered marker, and main shell required");
|
|
863
|
+
support.forEach((expected, index) => this.compareTree(nodes[index], expected, canonical));
|
|
864
|
+
const programMarker = nodes[support.length];
|
|
865
|
+
if (programMarker.type != "comment" || this.marker(programMarker) != "// semantifold:program:zig:v1") {
|
|
866
|
+
this.fail(programMarker, "exact generated Zig ordered-expression marker required");
|
|
867
|
+
}
|
|
868
|
+
this.generated = true;
|
|
869
|
+
const definitions = nodes.slice(support.length + 1);
|
|
870
|
+
/** @type {CstNode | undefined} */
|
|
871
|
+
let main;
|
|
872
|
+
/** @type {CstNode[]} */
|
|
873
|
+
const functions = [];
|
|
874
|
+
for (const node of definitions) {
|
|
875
|
+
if (node.type != "function_declaration")
|
|
876
|
+
this.fail(node, "top-level free functions only");
|
|
877
|
+
const name = this.text(this.field(node, "name"));
|
|
878
|
+
if (name == "main") {
|
|
879
|
+
if (main)
|
|
880
|
+
this.fail(node, "duplicate main");
|
|
881
|
+
main = node;
|
|
882
|
+
}
|
|
883
|
+
else {
|
|
884
|
+
if (main)
|
|
885
|
+
this.fail(node, "semantic function after main");
|
|
886
|
+
functions.push(node);
|
|
887
|
+
}
|
|
888
|
+
}
|
|
889
|
+
if (!main)
|
|
890
|
+
this.fail(root, "canonical pub fn main() void required");
|
|
891
|
+
const mainParts = this.parts(main);
|
|
892
|
+
const mainName = this.field(main, "name");
|
|
893
|
+
const parameters = mainParts.find(child => child.type == "parameters");
|
|
894
|
+
const returnType = this.field(main, "type");
|
|
895
|
+
const body = this.field(main, "body");
|
|
896
|
+
if (!parameters)
|
|
897
|
+
this.fail(main, "main parameters");
|
|
898
|
+
this.shape(main, ["pub", "fn", mainName, parameters, returnType, body]);
|
|
899
|
+
if (this.text(mainName) != "main")
|
|
900
|
+
this.fail(mainName, "main name");
|
|
901
|
+
this.shape(parameters, ["(", ")"]);
|
|
902
|
+
this.type(returnType, true);
|
|
903
|
+
if (this.text(returnType) != "void")
|
|
904
|
+
this.fail(returnType, "main return type");
|
|
905
|
+
const bodyParts = this.parts(body);
|
|
906
|
+
const deferNode = bodyParts[1];
|
|
907
|
+
const shellSource = "pub fn main() void {\n defer semantifold_arena.deinit();\n}\n";
|
|
908
|
+
const shellReader = new ZigReader(this.filename, shellSource);
|
|
909
|
+
const shellMain = shellReader.parts(parseZigCst(shellSource).root)[0];
|
|
910
|
+
const expectedDefer = shellReader.parts(shellReader.field(shellMain, "body"))[1];
|
|
911
|
+
if (!deferNode)
|
|
912
|
+
this.fail(body, "arena lifetime defer required");
|
|
913
|
+
this.compareTree(deferNode, expectedDefer, shellReader);
|
|
914
|
+
const module = validateParsedModule({ kind: "Module", location: this.location(root), functions: functions.map(node => this.function(node)),
|
|
915
|
+
entryPoint: { kind: "EntryPoint", location: this.location(main), body: this.block(body, 1) } }, "zig");
|
|
916
|
+
this.functions = new Map(module.functions.map(declaration => [declaration.name,
|
|
917
|
+
/** @type {import("../semantic/types.js").TypeReference} */ (declaration.returnType).name]));
|
|
918
|
+
for (const declaration of module.functions)
|
|
919
|
+
this.validateOperations(declaration.body);
|
|
920
|
+
this.validateOperations(module.entryPoint.body);
|
|
921
|
+
for (const declaration of module.functions)
|
|
922
|
+
this.validatePrints(declaration.body, new Map(declaration.parameters.map(parameter => [parameter.name,
|
|
923
|
+
/** @type {import("../semantic/types.js").TypeReference} */ (parameter.type).name])));
|
|
924
|
+
this.validatePrints(module.entryPoint.body, new Map());
|
|
925
|
+
for (const declaration of module.functions)
|
|
926
|
+
this.validateScaffolds(declaration);
|
|
927
|
+
this.validateScaffolds(module.entryPoint);
|
|
928
|
+
const canonicalSource = generateZigProject({ module }).artifacts[1]?.content;
|
|
929
|
+
if (typeof canonicalSource != "string")
|
|
930
|
+
throw new Error("Zig backend returned a nontext entry artifact.");
|
|
931
|
+
this.compareTree(root, parseZigCst(canonicalSource).root, new ZigReader(this.filename, canonicalSource));
|
|
932
|
+
return module;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Parses only the qualified frozen Zig CST and rejects unsupported input before adaptation.
|
|
937
|
+
* @param {{filename: string, source: string}} input - Exact source request.
|
|
938
|
+
* @returns {import("../semantic/types.js").SemanticModule} Zig semantic module.
|
|
939
|
+
*/
|
|
940
|
+
export function parseZig({ filename, source }) {
|
|
941
|
+
const coordinates = createCoordinateIndex(source);
|
|
942
|
+
const location = { filename, start: indexedPointAt(coordinates, 0), end: indexedPointAt(coordinates, source.length) };
|
|
943
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
944
|
+
const offset = source.search(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/u);
|
|
945
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "zig", message: "Zig source contains a lone UTF-16 surrogate.",
|
|
946
|
+
location: { filename, start: indexedPointAt(coordinates, offset), end: indexedPointAt(coordinates, offset + 1) } });
|
|
947
|
+
}
|
|
948
|
+
if (source.length > maximumZigSourceLength)
|
|
949
|
+
return unsupportedSyntax("zig", "source exceeds the 1000000 UTF-16 input limit", location);
|
|
950
|
+
let snapshot;
|
|
951
|
+
try {
|
|
952
|
+
snapshot = parseZigCst(source);
|
|
953
|
+
}
|
|
954
|
+
catch (error) {
|
|
955
|
+
throw new SemantifoldDiagnostic({ code: "PARSE_ERROR", language: "zig", location,
|
|
956
|
+
cause: error instanceof Error ? error : undefined, message: "The qualified Zig parser could not produce a complete CST." });
|
|
957
|
+
}
|
|
958
|
+
const reader = new ZigReader(filename, source);
|
|
959
|
+
try {
|
|
960
|
+
return reader.module(snapshot.root);
|
|
961
|
+
}
|
|
962
|
+
catch (error) {
|
|
963
|
+
if (reader.generated && error instanceof SemantifoldDiagnostic && error.language == "zig" &&
|
|
964
|
+
error.code != "PARSE_ERROR" && error.code != "UNSUPPORTED_SYNTAX") {
|
|
965
|
+
return unsupportedSyntax("zig", `invalid generated ordered scaffold: ${error.code}`, error.location ?? location);
|
|
966
|
+
}
|
|
967
|
+
throw error;
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiemlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy96aWcuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSxvQkFBb0IsQ0FBQTtBQUNyRCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDckQsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sK0JBQStCLENBQUE7QUFDcEUsT0FBTyxFQUFDLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGtCQUFrQixDQUFBO0FBQ3RGLE9BQU8sRUFBQyxxQkFBcUIsRUFBRSxjQUFjLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUM3RSxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUM3RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUM1RCxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUM1RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFDN0MsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGlCQUFpQixDQUFBO0FBQzNDLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLG9CQUFvQixDQUFBO0FBRXpELDJEQUEyRDtBQUMzRCxzRUFBc0U7QUFDdEUsb0VBQW9FO0FBQ3BFLDhFQUE4RTtBQUU5RSxNQUFNLGdCQUFnQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQy9CLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFF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LEVBQUUsV0FBVyxDQUFDLENBQUE7UUFDL0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDckMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLGFBQWEsQ0FBQyxDQUFBO1FBRS9FLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDMUYsTUFBTSxTQUFTLEdBQUcsRUFBQyxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxhQUFhLENBQUMsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsRUFBQyxDQUFBO1FBRTVLLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTyxTQUFTLENBQUE7UUFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsYUFBYSxDQUFDLENBQUE7UUFFckQsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtRQUN6QyxJQUFJLE1BQU0sQ0FBQyxJQUFJLElBQUksbUJBQW1CO1lBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsNEJBQTRCLENBQUMsQ0FBQTtRQUN2RixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFD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QUFLLFlBQVkscUJBQXFCLElBQUksS0FBSyxDQUFDLFFBQVEsSUFBSSxLQUFLO1lBQ3ZGLEtBQUssQ0FBQyxJQUFJLElBQUksYUFBYSxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksb0JBQW9CLEVBQUUsQ0FBQztZQUNwRSxPQUFPLGlCQUFpQixDQUFDLEtBQUssRUFBRSx1Q0FBdUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLEtBQUssQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLENBQUE7UUFDbEgsQ0FBQztRQUNELE1BQU0sS0FBSyxDQUFBO0lBQ2IsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtpc1ppZ0lkZW50aWZpZXJ9IGZyb20gXCIuLi9iYWNrZW5kcy9pZGVudGlmaWVycy5qc1wiXG5pbXBvcnQge2dlbmVyYXRlWmlnUHJvamVjdH0gZnJvbSBcIi4uL2JhY2tlbmRzL3ppZy5qc1wiXG5pbXBvcnQge3ppZ1J1bnRpbWV9IGZyb20gXCIuLi9iYWNrZW5kcy96aWctcnVudGltZS5qc1wiXG5pbXBvcnQge21heGltdW1aaWdTb3VyY2VMZW5ndGh9IGZyb20gXCIuLi9iYWNrZW5kcy96aWctdmFsaWRhdGlvbi5qc1wiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBTZW1hbnRpZm9sZERpYWdub3N0aWMsIHVuc3VwcG9ydGVkU3ludGF4fSBmcm9tIFwiLi4vZGlhZ25vc3RpYy5qc1wiXG5pbXBvcnQge2NyZWF0ZUNvb3JkaW5hdGVJbmRleCwgaW5kZXhlZFBvaW50QXR9IGZyb20gXCIuLi9zZW1hbnRpYy9sb2NhdGlvbi5qc1wiXG5pbXBvcnQge3dpdGhBZGFwdGVkT3BlcmF0aW9ufSBmcm9tIFwiLi4vc2VtYW50aWMvb3BlcmF0b3JzLmpzXCJcbmltcG9ydCB7d2l0aFBhcnNlclJhbmdlc30gZnJvbSBcIi4uL3NlbWFudGljL3Byb3ZlbmFuY2UuanNcIlxuaW1wb3J0IHtoYXNPbmx5VW5pY29kZVNjYWxhcnN9IGZyb20gXCIuLi9zZW1hbnRpYy9zY2FsYXJzLmpzXCJcbmltcG9ydCB7dmFsaWRhdGVQYXJzZWRNb2R1bGV9IGZyb20gXCIuLi9zZW1hbnRpYy92YWxpZGF0ZS5qc1wiXG5pbXBvcnQge3NvdXJjZVNjYWxhclR5cGV9IGZyb20gXCIuL3NjYWxhcnMuanNcIlxuaW1wb3J0IHtwYXJzZVppZ0NzdH0gZnJvbSBcIi4vemlnLXBhcnNlci5qc1wiXG5pbXBvcnQge2NvbGxlY3RaaWdCaW5kaW5nVXNhZ2V9IGZyb20gXCIuLi96aWctYmluZGluZ3MuanNcIlxuXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4vemlnLXBhcnNlci5qc1wiKS5Dc3ROb2RlfSBDc3ROb2RlICovXG4vKiogQHR5cGVkZWYge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259IEV4cHJlc3Npb24gKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU3RhdGVtZW50fSBTdGF0ZW1lbnQgKi9cbi8qKiBAdHlwZWRlZiB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25SZXR1cm5UeXBlTmFtZX0gU2NhbGFyICovXG5cbmNvbnN0IGJpbmFyeU9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wiK1wiLCBcIkFkZFwiXSwgW1wiLVwiLCBcIlN1YnRyYWN0XCJdLCBbXCIqXCIsIFwiTXVsdGlwbHlcIl0sIFtcIj09XCIsIFwiRXF1YWxcIl0sIFtcIiE9XCIsIFwiTm90RXF1YWxcIl0sXG4gIFtcIjxcIiwgXCJMZXNzVGhhblwiXSwgW1wiPD1cIiwgXCJMZXNzVGhhbk9yRXF1YWxcIl0sIFtcIj5cIiwgXCJHcmVhdGVyVGhhblwiXSwgW1wiPj1cIiwgXCJHcmVhdGVyVGhhbk9yRXF1YWxcIl0sXG4gIFtcImFuZFwiLCBcIkFuZFwiXSwgW1wib3JcIiwgXCJPclwiXVxuXSlcbmNvbnN0IGhlbHBlck9wZXJhdGlvbnMgPSBuZXcgTWFwKFtcbiAgW1wic2VtYW50aWZvbGRfaW50ZWdlcl9hZGRcIiwgXCJBZGRcIl0sIFtcInNlbWFudGlmb2xkX2ludGVnZXJfc3VidHJhY3RcIiwgXCJTdWJ0cmFjdFwiXSxcbiAgW1wic2VtYW50aWZvbGRfaW50ZWdlcl9tdWx0aXBseVwiLCBcIk11bHRpcGx5XCJdLCBbXCJzZW1hbnRpZm9sZF9zdHJpbmdfY29uY2F0XCIsIFwiQWRkXCJdLFxuICBbXCJzZW1hbnRpZm9sZF9zdHJpbmdfZXF1YWxcIiwgXCJFcXVhbFwiXSwgW1wic2VtYW50aWZvbGRfc3RyaW5nX25vdF9lcXVhbFwiLCBcIk5vdEVxdWFsXCJdXG5dKVxuY29uc3Qgb3BlcmF0aW9uU3BlbGxpbmdzID0gbmV3IE1hcChbXG4gIFtcIkludGVnZXJBZGRcIiwgXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX2FkZFwiXSwgW1wiSW50ZWdlclN1YnRyYWN0XCIsIFwic2VtYW50aWZvbGRfaW50ZWdlcl9zdWJ0cmFjdFwiXSxcbiAgW1wiSW50ZWdlck11bHRpcGx5XCIsIFwic2VtYW50aWZvbGRfaW50ZWdlcl9tdWx0aXBseVwiXSwgW1wiSW50ZWdlck5lZ2F0ZVwiLCBcInNlbWFudGlmb2xkX2ludGVnZXJfbmVnYXRlXCJdLFxuICBbXCJJbnRlZ2VyRXF1YWxcIiwgXCI9PVwiXSwgW1wiSW50ZWdlck5vdEVxdWFsXCIsIFwiIT1cIl0sIFtcIkludGVnZXJMZXNzVGhhblwiLCBcIjxcIl0sXG4gIFtcIkludGVnZXJMZXNzVGhhbk9yRXF1YWxcIiwgXCI8PVwiXSwgW1wiSW50ZWdlckdyZWF0ZXJUaGFuXCIsIFwiPlwiXSwgW1wiSW50ZWdlckdyZWF0ZXJUaGFuT3JFcXVhbFwiLCBcIj49XCJdLFxuICBbXCJCb29sZWFuRXF1YWxcIiwgXCI9PVwiXSwgW1wiQm9vbGVhbk5vdEVxdWFsXCIsIFwiIT1cIl0sIFtcIkJvb2xlYW5BbmRcIiwgXCJhbmRcIl0sIFtcIkJvb2xlYW5PclwiLCBcIm9yXCJdLCBbXCJCb29sZWFuTm90XCIsIFwiIVwiXSxcbiAgW1wiU3RyaW5nQ29uY2F0XCIsIFwic2VtYW50aWZvbGRfc3RyaW5nX2NvbmNhdFwiXSwgW1wiU3RyaW5nRXF1YWxcIiwgXCJzZW1hbnRpZm9sZF9zdHJpbmdfZXF1YWxcIl0sXG4gIFtcIlN0cmluZ05vdEVxdWFsXCIsIFwic2VtYW50aWZvbGRfc3RyaW5nX25vdF9lcXVhbFwiXVxuXSlcblxuLyoqIENvbnN1bWVzIHRoZSBjb21wbGV0ZSBxdWFsaWZpZWQgWmlnIENTVCBhbmQgcmV0YWlucyBleGFjdCBnZW5lcmF0ZWQtc2hlbGwgY29uc3RyYWludHMuICovXG5jbGFzcyBaaWdSZWFkZXIge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHJlYWRlciBvdmVyIG9uZSBjb21wbGV0ZSBwYXJzZXIgc25hcHNob3QuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIExvZ2ljYWwgc291cmNlIGZpbGVuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gRXhhY3QgWmlnIHNvdXJjZSB0ZXh0LlxuICAgKi9cbiAgY29uc3RydWN0b3IoZmlsZW5hbWUsIHNvdXJjZSkge1xuICAgIHRoaXMuZmlsZW5hbWUgPSBmaWxlbmFtZVxuICAgIHRoaXMuc291cmNlID0gc291cmNlXG4gICAgdGhpcy5jb29yZGluYXRlcyA9IGNyZWF0ZUNvb3JkaW5hdGVJbmRleChzb3VyY2UpXG4gICAgdGhpcy5nZW5lcmF0ZWQgPSBmYWxzZVxuICAgIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgRXhwcmVzc2lvbj4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy50ZW1wb3JhcnlFeHByZXNzaW9ucyA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7U2V0PHN0cmluZz4gfCB1bmRlZmluZWR9ICovXG4gICAgdGhpcy50ZW1wb3JhcnlOYW1lcyA9IHVuZGVmaW5lZFxuICAgIC8qKiBAdHlwZSB7TWFwPEV4cHJlc3Npb24sIHtub2RlOiBDc3ROb2RlLCBzcGVsbGluZzogc3RyaW5nfT59ICovXG4gICAgdGhpcy5vcGVyYXRpb25zID0gbmV3IE1hcCgpXG4gICAgLyoqIEB0eXBlIHtNYXA8U3RhdGVtZW50LCB7bm9kZTogQ3N0Tm9kZSwgdHlwZTogc3RyaW5nfT59ICovXG4gICAgdGhpcy5wcmludHMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxzdHJpbmcsIFNjYWxhcj59ICovXG4gICAgdGhpcy5mdW5jdGlvbnMgPSBuZXcgTWFwKClcbiAgICAvKiogQHR5cGUge01hcDxpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QYXJhbWV0ZXIgfCBpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Mb2NhbERlY2xhcmF0aW9uLCBcInVzZVwiIHwgXCJhZGRyZXNzXCIgfCBcIm5vbmVcIj59ICovXG4gICAgdGhpcy5zY2FmZm9sZHMgPSBuZXcgTWFwKClcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhIHBhcnNlciBub2RlIGJvdW5kYXJ5IHRvIGEgc2VtYW50aWMgbG9jYXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IFVURi0xNiBsb2NhdGlvbi5cbiAgICovXG4gIGxvY2F0aW9uKG5vZGUpIHtcbiAgICByZXR1cm4ge2ZpbGVuYW1lOiB0aGlzLmZpbGVuYW1lLCBzdGFydDogaW5kZXhlZFBvaW50QXQodGhpcy5jb29yZGluYXRlcywgbm9kZS5zdGFydEluZGV4KSwgZW5kOiBpbmRleGVkUG9pbnRBdCh0aGlzLmNvb3JkaW5hdGVzLCBub2RlLmVuZEluZGV4KX1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyB0aGUgZXhhY3Qgc291cmNlIHNwZWxsaW5nIG93bmVkIGJ5IGEgcGFyc2VyIG5vZGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBOb2RlIHNvdXJjZSB0ZXh0LlxuICAgKi9cbiAgdGV4dChub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuc291cmNlLnNsaWNlKG5vZGUuc3RhcnRJbmRleCwgbm9kZS5lbmRJbmRleClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkcyBvbmUgZ2VuZXJhdGVkIGxpbmUtY29tbWVudCBtYXJrZXIgaW5kZXBlbmRlbnQgb2YgdGhlIHNvdXJjZSBuZXdsaW5lIGNvbnZlbnRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIE1hcmtlciBjb21tZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IE1hcmtlciBzcGVsbGluZyB3aXRob3V0IGEgcGFyc2VyLW93bmVkIHRyYWlsaW5nIGNhcnJpYWdlIHJldHVybi5cbiAgICovXG4gIG1hcmtlcihub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMudGV4dChub2RlKS5yZXBsYWNlKC9cXHIkL3UsIFwiXCIpXG4gIH1cblxuICAvKipcbiAgICogUmFpc2VzIGEgbG9jYXRlZCB1bnN1cHBvcnRlZC1zeW50YXggZGlhZ25vc3RpYy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gUmVqZWN0ZWQgcGFyc2VyIG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbZGV0YWlsXSAtIERpYWdub3N0aWMgZGV0YWlsLlxuICAgKiBAcmV0dXJucyB7bmV2ZXJ9IFRoaXMgZnVuY3Rpb24gYWx3YXlzIHRocm93cy5cbiAgICovXG4gIGZhaWwobm9kZSwgZGV0YWlsID0gbm9kZS50eXBlKSB7XG4gICAgdW5zdXBwb3J0ZWRTeW50YXgoXCJ6aWdcIiwgZGV0YWlsLCB0aGlzLmxvY2F0aW9uKG5vZGUpKVxuICB9XG5cbiAgLyoqXG4gICAqIEV4aGF1c3RpdmVseSByZWplY3RzIHJlY292ZXJ5LCB1bmV4cGVjdGVkIGV4dHJhcywgZGlyZWN0aXZlcywgYW5kIGV4Y2Vzc2l2ZSBuZXN0aW5nLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDdXJyZW50IENTVCBub2RlLlxuICAgKiBAcGFyYW0ge251bWJlcn0gW2RlcHRoXSAtIEN1cnJlbnQgbmVzdGluZyBkZXB0aC5cbiAgICovXG4gIHZhbGlkYXRlVHJlZShub2RlLCBkZXB0aCA9IDApIHtcbiAgICBpZiAoZGVwdGggPiA1MTIpIHRoaXMuZmFpbChub2RlLCBcIlppZyBDU1QgZXhjZWVkcyB0aGUgNTEyLWxldmVsIHRyYXZlcnNhbCBsaW1pdFwiKVxuICAgIGZvciAoY29uc3Qge25vZGU6IGNoaWxkfSBvZiBub2RlLmNoaWxkcmVuKSB0aGlzLnZhbGlkYXRlVHJlZShjaGlsZCwgZGVwdGggKyAxKVxuICAgIGlmIChub2RlLmVycm9yIHx8IG5vZGUubWlzc2luZyB8fCBub2RlLmhhc0Vycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInppZ1wiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbWVzc2FnZTogYFppZyBwYXJzZXIgcmVjb3ZlcnkgYXQgJyR7bm9kZS50eXBlfScuYH0pXG4gICAgfVxuICAgIGlmIChub2RlLmV4dHJhICYmIG5vZGUudHlwZSAhPSBcImNvbW1lbnRcIikgdGhpcy5mYWlsKG5vZGUsIFwidW5leHBlY3RlZCBleHRyYSBwYXJzZXIgY2hpbGRcIilcbiAgICBpZiAobm9kZS50eXBlID09IFwiY29tbWVudFwiICYmICgvXlxccypcXC9cXC9bLyFdL3UudGVzdCh0aGlzLnRleHQobm9kZSkpIHx8IC9eXFxzKlxcL1xcL1xccyp6aWcgZm10Oi91LnRlc3QodGhpcy50ZXh0KG5vZGUpKSkpIHtcbiAgICAgIHRoaXMuZmFpbChub2RlLCBcImRvYyBvciBmb3JtYXR0ZXItZGlyZWN0aXZlIGNvbW1lbnRcIilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBldmVyeSBub24tY29tbWVudCBjaGlsZCB3aXRob3V0IGhpZGluZyBzeW50YXggZWRnZXMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHJldHVybnMge0NzdE5vZGVbXX0gT3JkZXJlZCBub24tY29tbWVudCBjaGlsZHJlbi5cbiAgICovXG4gIHBhcnRzKG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5jaGlsZHJlbi5tYXAoKHtub2RlOiBjaGlsZH0pID0+IGNoaWxkKS5maWx0ZXIoY2hpbGQgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRhaW5zIGNvbXBpbGVyLW93bmVkIHNjYWZmb2xkIG1hcmtlcnMgd2hpbGUgaWdub3Jpbmcgb3JkaW5hcnkgaW5lcnQgY29tbWVudHMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHJldHVybnMge0NzdE5vZGVbXX0gQ29tcGxldGUgc2lnbmlmaWNhbnQgY2hpbGQgbGlzdC5cbiAgICovXG4gIHNpZ25pZmljYW50KG5vZGUpIHtcbiAgICByZXR1cm4gbm9kZS5jaGlsZHJlbi5tYXAoKHtub2RlOiBjaGlsZH0pID0+IGNoaWxkKS5maWx0ZXIoY2hpbGQgPT5cbiAgICAgIGNoaWxkLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgL3NlbWFudGlmb2xkOi91LnRlc3QodGhpcy50ZXh0KGNoaWxkKSkpXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgZXhhY3RseSBvbmUgcGFyc2VyIGZpZWxkIGVkZ2UuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcmVudCBwYXJzZXIgbm9kZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBSZXF1aXJlZCBmaWVsZCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Q3N0Tm9kZX0gRmllbGQgY2hpbGQuXG4gICAqL1xuICBmaWVsZChub2RlLCBuYW1lKSB7XG4gICAgY29uc3QgZWRnZXMgPSBub2RlLmNoaWxkcmVuLmZpbHRlcigoe2ZpZWxkfSkgPT4gZmllbGQgPT0gbmFtZSlcblxuICAgIGlmIChlZGdlcy5sZW5ndGggIT0gMSkgdGhpcy5mYWlsKG5vZGUsIGBleHBlY3RlZCBvbmUgJyR7bmFtZX0nIGZpZWxkYClcbiAgICByZXR1cm4gZWRnZXNbMF0ubm9kZVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcXVpcmVzIGFuIGV4YWN0IG9yZGVyZWQgY2hpbGQvdG9rZW4gc2hhcGUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlIHRvIGNoZWNrLlxuICAgKiBAcGFyYW0geyhDc3ROb2RlIHwgc3RyaW5nKVtdfSBleHBlY3RlZCAtIEV4cGVjdGVkIG5vZGUgaWRlbnRpdGllcyBvciB0b2tlbiB0eXBlcy5cbiAgICovXG4gIHNoYXBlKG5vZGUsIGV4cGVjdGVkKSB7XG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICBpZiAocGFydHMubGVuZ3RoICE9IGV4cGVjdGVkLmxlbmd0aCB8fCBwYXJ0cy5zb21lKChjaGlsZCwgaW5kZXgpID0+XG4gICAgICB0eXBlb2YgZXhwZWN0ZWRbaW5kZXhdID09IFwic3RyaW5nXCIgPyBjaGlsZC50eXBlICE9IGV4cGVjdGVkW2luZGV4XSB8fCAhY2hpbGQubmFtZWQgJiYgdGhpcy50ZXh0KGNoaWxkKSAhPSBleHBlY3RlZFtpbmRleF0gOiBjaGlsZCAhPT0gZXhwZWN0ZWRbaW5kZXhdKSkge1xuICAgICAgdGhpcy5mYWlsKG5vZGUsIGAke25vZGUudHlwZX0gY2hpbGQgc2hhcGVgKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBWYWxpZGF0ZXMgYW5kIHJldHVybnMgb25lIG9yZGluYXJ5IFppZyBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgaWRlbnRpZmllciBub2RlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSBWYWxpZGF0ZWQgaWRlbnRpZmllci5cbiAgICovXG4gIGlkZW50aWZpZXIobm9kZSkge1xuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgIWlzWmlnSWRlbnRpZmllcihuYW1lKSkgdGhpcy5mYWlsKG5vZGUsIFwicmVzZXJ2ZWQgb3IgdW5zdXBwb3J0ZWQgaWRlbnRpZmllclwiKVxuICAgIHJldHVybiBuYW1lXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYW4gZXhhY3Qgc291cmNlIHNjYWxhciBhbm5vdGF0aW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBUeXBlIG5vZGUuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FsbG93Vm9pZF0gLSBXaGV0aGVyIHZvaWQgaXMgdmFsaWQgaGVyZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljRnVuY3Rpb25SZXR1cm5UeXBlfSBTZW1hbnRpYyB0eXBlLlxuICAgKi9cbiAgdHlwZShub2RlLCBhbGxvd1ZvaWQgPSBmYWxzZSkge1xuICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KG5vZGUpXG5cbiAgICBpZiAoYWxsb3dWb2lkICYmIG5vZGUudHlwZSA9PSBcImJ1aWx0aW5fdHlwZVwiICYmIHNwZWxsaW5nID09IFwidm9pZFwiKSB7XG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcInZvaWRcIl0pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJUeXBlUmVmZXJlbmNlXCIsIG5hbWU6IFwidm9pZFwifSwge3R5cGU6IHRoaXMubG9jYXRpb24obm9kZSl9KVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiYnVpbHRpbl90eXBlXCIgJiYgW1wiaTY0XCIsIFwiYm9vbFwiXS5pbmNsdWRlcyhzcGVsbGluZykpIHtcbiAgICAgIGlmIChzcGVsbGluZyA9PSBcImJvb2xcIikgdGhpcy5zaGFwZShub2RlLCBbXCJib29sXCJdKVxuICAgICAgZWxzZSBpZiAobm9kZS5jaGlsZHJlbi5sZW5ndGgpIHRoaXMuZmFpbChub2RlLCBcInNjYWxhciB0eXBlIHNoYXBlXCIpXG4gICAgfSBlbHNlIGlmIChub2RlLnR5cGUgPT0gXCJzbGljZV90eXBlXCIgJiYgc3BlbGxpbmcgPT0gXCJbXWNvbnN0IHU4XCIpIHtcbiAgICAgIHRoaXMuc2hhcGUobm9kZSwgW1wiW1wiLCBcIl1cIiwgXCJjb25zdFwiLCB0aGlzLnBhcnRzKG5vZGUpWzNdXSlcbiAgICAgIGNvbnN0IGNoaWxkID0gdGhpcy5wYXJ0cyhub2RlKVszXVxuXG4gICAgICBpZiAoY2hpbGQudHlwZSAhPSBcImJ1aWx0aW5fdHlwZVwiIHx8IHRoaXMudGV4dChjaGlsZCkgIT0gXCJ1OFwiIHx8IGNoaWxkLmNoaWxkcmVuLmxlbmd0aCkgdGhpcy5mYWlsKGNoaWxkLCBcImltbXV0YWJsZSBVVEYtOCBzbGljZSBlbGVtZW50XCIpXG4gICAgfSBlbHNlIHJldHVybiBtaXNzaW5nVHlwZShcInppZ1wiLCBhbGxvd1ZvaWQgPyBcImZ1bmN0aW9uIHJldHVyblwiIDogXCJzY2FsYXJcIiwgdGhpcy5sb2NhdGlvbihub2RlKSlcbiAgICBjb25zdCB0eXBlID0gc291cmNlU2NhbGFyVHlwZShcInppZ1wiLCBzcGVsbGluZywgdGhpcy5sb2NhdGlvbihub2RlKSlcblxuICAgIGlmICghdHlwZSkgcmV0dXJuIG1pc3NpbmdUeXBlKFwiemlnXCIsIFwic2NhbGFyXCIsIHRoaXMubG9jYXRpb24obm9kZSkpXG4gICAgcmV0dXJuIHR5cGVcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvbXBvc2VzIGFuIGV4YWN0IGRpcmVjdCBjYWxsLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYWxsIGV4cHJlc3Npb24gbm9kZS5cbiAgICogQHJldHVybnMge3tuYW1lOiBDc3ROb2RlLCBhcmd1bWVudHM6IENzdE5vZGVbXX19IENhbGxlZSBhbmQgb3JkZXJlZCBhcmd1bWVudHMuXG4gICAqL1xuICBjYWxsKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwiY2FsbF9leHByZXNzaW9uXCIpIHRoaXMuZmFpbChub2RlLCBcImRpcmVjdCBjYWxsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgbmFtZSA9IHRoaXMuZmllbGQobm9kZSwgXCJmdW5jdGlvblwiKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuICAgIGNvbnN0IGFyZ3VtZW50c0FuZENvbW1hcyA9IHBhcnRzLnNsaWNlKDIsIC0xKVxuICAgIGNvbnN0IGFyZ3MgPSBhcmd1bWVudHNBbmRDb21tYXMuZmlsdGVyKChfcGFydCwgaW5kZXgpID0+IGluZGV4ICUgMiA9PSAwKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbbmFtZSwgXCIoXCIsIC4uLmFyZ3MuZmxhdE1hcCgoYXJndW1lbnQsIGluZGV4KSA9PiBpbmRleCA/IFtcIixcIiwgYXJndW1lbnRdIDogW2FyZ3VtZW50XSksIFwiKVwiXSlcbiAgICByZXR1cm4ge25hbWUsIGFyZ3VtZW50czogYXJnc31cbiAgfVxuXG4gIC8qKlxuICAgKiBEZWNvZGVzIG9uZSBib3VuZGVkIG9yZGluYXJ5IFppZyBzdHJpbmcgbGl0ZXJhbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gU3RyaW5nIG5vZGUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9IFVuaWNvZGUgc2NhbGFyIHZhbHVlLlxuICAgKi9cbiAgc3RyaW5nKG5vZGUpIHtcbiAgICBpZiAobm9kZS50eXBlICE9IFwic3RyaW5nXCIpIHRoaXMuZmFpbChub2RlLCBcIm9yZGluYXJ5IFVURi04IHN0cmluZyBsaXRlcmFsIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFsnXCInLCAuLi5wYXJ0cy5zbGljZSgxLCAtMSksICdcIiddKVxuICAgIGxldCB2YWx1ZSA9IFwiXCJcblxuICAgIGZvciAoY29uc3QgcGFydCBvZiBwYXJ0cy5zbGljZSgxLCAtMSkpIHtcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KHBhcnQpXG5cbiAgICAgIGlmIChwYXJ0LnR5cGUgPT0gXCJzdHJpbmdfY29udGVudFwiKSB7XG4gICAgICAgIGlmICgvW1xcclxcbl0vdS50ZXN0KHNwZWxsaW5nKSkgdGhpcy5mYWlsKHBhcnQsIFwicmF3IHN0cmluZyBsaW5lIHRlcm1pbmF0b3JcIilcbiAgICAgICAgdmFsdWUgKz0gc3BlbGxpbmdcbiAgICAgIH0gZWxzZSBpZiAocGFydC50eXBlID09IFwiZXNjYXBlX3NlcXVlbmNlXCIpIHtcbiAgICAgICAgY29uc3Qgc2ltcGxlID0gbmV3IE1hcChbW1wiXFxcXG5cIiwgXCJcXG5cIl0sIFtcIlxcXFxyXCIsIFwiXFxyXCJdLCBbXCJcXFxcdFwiLCBcIlxcdFwiXSwgW1wiXFxcXFxcXFxcIiwgXCJcXFxcXCJdLCBbJ1xcXFxcIicsICdcIiddXSlcblxuICAgICAgICBpZiAoc2ltcGxlLmhhcyhzcGVsbGluZykpIHZhbHVlICs9IHNpbXBsZS5nZXQoc3BlbGxpbmcpXG4gICAgICAgIGVsc2UgaWYgKC9eXFxcXHhbMC05YS1mQS1GXXsyfSQvdS50ZXN0KHNwZWxsaW5nKSkge1xuICAgICAgICAgIGNvbnN0IHNjYWxhciA9IE51bWJlci5wYXJzZUludChzcGVsbGluZy5zbGljZSgyKSwgMTYpXG5cbiAgICAgICAgICBpZiAoc2NhbGFyID4gMTI3KSB0aGlzLmZhaWwocGFydCwgXCJub24tQVNDSUkgYnl0ZSBlc2NhcGVcIilcbiAgICAgICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChzY2FsYXIpXG4gICAgICAgIH0gZWxzZSBpZiAoL15cXFxcdVxce1swLTlhLWZBLUZdezEsNn1cXH0kL3UudGVzdChzcGVsbGluZykpIHtcbiAgICAgICAgICBjb25zdCBzY2FsYXIgPSBOdW1iZXIucGFyc2VJbnQoc3BlbGxpbmcuc2xpY2UoMywgLTEpLCAxNilcblxuICAgICAgICAgIGlmIChzY2FsYXIgPiAweDEwRkZGRiB8fCBzY2FsYXIgPj0gMHhEODAwICYmIHNjYWxhciA8PSAweERGRkYpIHRoaXMuZmFpbChwYXJ0LCBcIm5vbi1zY2FsYXIgVW5pY29kZSBlc2NhcGVcIilcbiAgICAgICAgICB2YWx1ZSArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChzY2FsYXIpXG4gICAgICAgIH0gZWxzZSB0aGlzLmZhaWwocGFydCwgXCJ1bnN1cHBvcnRlZCBzdHJpbmcgZXNjYXBlXCIpXG4gICAgICB9IGVsc2UgdGhpcy5mYWlsKHBhcnQsIFwic3RyaW5nIGNoaWxkXCIpXG4gICAgfVxuICAgIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHZhbHVlKSkgdGhpcy5mYWlsKG5vZGUsIFwibm9uLXNjYWxhciBzdHJpbmcgdmFsdWVcIilcbiAgICByZXR1cm4gdmFsdWVcbiAgfVxuXG4gIC8qKlxuICAgKiBDb252ZXJ0cyBvbmUgc3VwcG9ydGVkIHNjYWxhciBleHByZXNzaW9uLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBFeHByZXNzaW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtFeHByZXNzaW9ufSBTZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgZXhwcmVzc2lvbihub2RlKSB7XG4gICAgY29uc3QgbG9jYXRpb24gPSB0aGlzLmxvY2F0aW9uKG5vZGUpXG5cbiAgICBpZiAobm9kZS50eXBlID09IFwicGFyZW50aGVzaXplZF9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtcIihcIiwgcGFydHNbMV0sIFwiKVwiXSlcbiAgICAgIHJldHVybiB0aGlzLmV4cHJlc3Npb24ocGFydHNbMV0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICAgIGNvbnN0IHRlbXBvcmFyeSA9IHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnM/LmdldCh0aGlzLnRleHQobm9kZSkpXG5cbiAgICAgIGlmICh0ZW1wb3JhcnkpIHtcbiAgICAgICAgdGhpcy50ZW1wb3JhcnlFeHByZXNzaW9ucz8uZGVsZXRlKHRoaXMudGV4dChub2RlKSlcbiAgICAgICAgcmV0dXJuIHRlbXBvcmFyeVxuICAgICAgfVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiwgbG9jYXRpb24sIG5hbWU6IHRoaXMuaWRlbnRpZmllcihub2RlKX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJpbnRlZ2VyXCIpIHtcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gdGhpcy50ZXh0KG5vZGUpXG4gICAgICBjb25zdCB2YWx1ZSA9IE51bWJlcihzcGVsbGluZylcblxuICAgICAgaWYgKCEvXig/OjB8WzEtOV1bMC05XSopJC91LnRlc3Qoc3BlbGxpbmcpIHx8ICFOdW1iZXIuaXNTYWZlSW50ZWdlcih2YWx1ZSkpIHRoaXMuZmFpbChub2RlLCBcIm5vbi1zYWZlIG9yIG5vbmNhbm9uaWNhbCBpNjQgbGl0ZXJhbFwiKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiSW50ZWdlckxpdGVyYWxcIiwgbG9jYXRpb24sIHZhbHVlfSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImJvb2xlYW5cIikge1xuICAgICAgY29uc3Qgc3BlbGxpbmcgPSB0aGlzLnRleHQobm9kZSlcblxuICAgICAgaWYgKHNwZWxsaW5nICE9IFwidHJ1ZVwiICYmIHNwZWxsaW5nICE9IFwiZmFsc2VcIikgdGhpcy5mYWlsKG5vZGUsIFwiQm9vbGVhbiBsaXRlcmFsIHNwZWxsaW5nXCIpXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFtzcGVsbGluZ10pXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJCb29sZWFuTGl0ZXJhbFwiLCBsb2NhdGlvbiwgdmFsdWU6IHNwZWxsaW5nID09IFwidHJ1ZVwifSwge2xpdGVyYWw6IGxvY2F0aW9ufSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInN0cmluZ1wiKSByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJTdHJpbmdMaXRlcmFsXCIsIGxvY2F0aW9uLCB2YWx1ZTogdGhpcy5zdHJpbmcobm9kZSl9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIgfHwgbm9kZS50eXBlID09IFwiZXJyb3JfdW5pb25fdHlwZVwiKSB7XG4gICAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gbm9kZS50eXBlID09IFwidW5hcnlfZXhwcmVzc2lvblwiID8gdGhpcy5maWVsZChub2RlLCBcIm9wZXJhdG9yXCIpIDogcGFydHNbMF1cbiAgICAgIGNvbnN0IG9wZXJhbmQgPSBub2RlLnR5cGUgPT0gXCJ1bmFyeV9leHByZXNzaW9uXCIgPyB0aGlzLmZpZWxkKG5vZGUsIFwiYXJndW1lbnRcIikgOiB0aGlzLmZpZWxkKG5vZGUsIFwib2tcIilcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbb3BlcmF0b3IsIG9wZXJhbmRdKVxuICAgICAgaWYgKG9wZXJhdG9yLnR5cGUgIT0gXCItXCIgJiYgb3BlcmF0b3IudHlwZSAhPSBcIiFcIikgdGhpcy5mYWlsKG9wZXJhdG9yLCBcInVuYXJ5IG9wZXJhdG9yXCIpXG4gICAgICByZXR1cm4gdGhpcy51bmFyeShub2RlLCBvcGVyYXRvci50eXBlID09IFwiLVwiID8gXCJOZWdhdGVcIiA6IFwiTm90XCIsIHRoaXMuZXhwcmVzc2lvbihvcGVyYW5kKSwgb3BlcmF0b3IpXG4gICAgfVxuICAgIGlmIChub2RlLnR5cGUgPT0gXCJiaW5hcnlfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBsZWZ0ID0gdGhpcy5maWVsZChub2RlLCBcImxlZnRcIilcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5maWVsZChub2RlLCBcInJpZ2h0XCIpXG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQobm9kZSwgXCJvcGVyYXRvclwiKVxuICAgICAgY29uc3QgaW50ZW50ID0gYmluYXJ5T3BlcmF0aW9ucy5nZXQob3BlcmF0b3IudHlwZSlcblxuICAgICAgdGhpcy5zaGFwZShub2RlLCBbbGVmdCwgb3BlcmF0b3IsIHJpZ2h0XSlcbiAgICAgIGlmICghaW50ZW50KSB0aGlzLmZhaWwob3BlcmF0b3IsIFwidW5zdXBwb3J0ZWQgYmluYXJ5IG9wZXJhdG9yXCIpXG4gICAgICByZXR1cm4gdGhpcy5iaW5hcnkobm9kZSwgaW50ZW50LCB0aGlzLmV4cHJlc3Npb24obGVmdCksIHRoaXMuZXhwcmVzc2lvbihyaWdodCksIG9wZXJhdG9yKVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlID09IFwiY2FsbF9leHByZXNzaW9uXCIpIHtcbiAgICAgIGNvbnN0IGNhbGwgPSB0aGlzLmNhbGwobm9kZSlcblxuICAgICAgaWYgKGNhbGwubmFtZS50eXBlICE9IFwiaWRlbnRpZmllclwiKSB0aGlzLmZhaWwoY2FsbC5uYW1lLCBcImRpcmVjdCBmdW5jdGlvbiBjYWxsIHJlcXVpcmVkXCIpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KGNhbGwubmFtZSlcblxuICAgICAgaWYgKG5hbWUgPT0gXCJzZW1hbnRpZm9sZF9pbnRlZ2VyX25lZ2F0ZVwiKSB7XG4gICAgICAgIGlmIChjYWxsLmFyZ3VtZW50cy5sZW5ndGggIT0gMSkgdGhpcy5mYWlsKG5vZGUsIFwibmVnYXRpb24gaGVscGVyIGFyaXR5XCIpXG4gICAgICAgIHJldHVybiB0aGlzLnVuYXJ5KG5vZGUsIFwiTmVnYXRlXCIsIHRoaXMuZXhwcmVzc2lvbihjYWxsLmFyZ3VtZW50c1swXSksIGNhbGwubmFtZSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IGludGVudCA9IGhlbHBlck9wZXJhdGlvbnMuZ2V0KG5hbWUpXG5cbiAgICAgIGlmIChpbnRlbnQpIHtcbiAgICAgICAgaWYgKGNhbGwuYXJndW1lbnRzLmxlbmd0aCAhPSAyKSB0aGlzLmZhaWwobm9kZSwgXCJvcGVyYXRvciBoZWxwZXIgYXJpdHlcIilcbiAgICAgICAgcmV0dXJuIHRoaXMuYmluYXJ5KG5vZGUsIGludGVudCwgdGhpcy5leHByZXNzaW9uKGNhbGwuYXJndW1lbnRzWzBdKSwgdGhpcy5leHByZXNzaW9uKGNhbGwuYXJndW1lbnRzWzFdKSwgY2FsbC5uYW1lKVxuICAgICAgfVxuICAgICAgaWYgKG5hbWUuc3RhcnRzV2l0aChcInNlbWFudGlmb2xkX1wiKSkgdGhpcy5mYWlsKGNhbGwubmFtZSwgXCJzdXBwb3J0IGhlbHBlciBvdXRzaWRlIGl0cyBleGFjdCBzZW1hbnRpYyByb2xlXCIpXG4gICAgICBjb25zdCBjYWxsZWUgPSB0aGlzLmlkZW50aWZpZXIoY2FsbC5uYW1lKVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJDYWxsRXhwcmVzc2lvblwiLCBsb2NhdGlvbiwgY2FsbGVlLCBhcmd1bWVudHM6IGNhbGwuYXJndW1lbnRzLm1hcChhcmd1bWVudCA9PiB0aGlzLmV4cHJlc3Npb24oYXJndW1lbnQpKX0sIHtjYWxsZWU6IHRoaXMubG9jYXRpb24oY2FsbC5uYW1lKX0pXG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZhaWwobm9kZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGFwdHMgb25lIHR5cGVkIGJpbmFyeSBvcGVyYXRvci5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gV2hvbGUgZXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW50ZW50IC0gU2hhcmVkIG9wZXJhdG9yIGludGVudC5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBsZWZ0IC0gTGVmdCBvcGVyYW5kLlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IHJpZ2h0IC0gUmlnaHQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBvcGVyYXRvciAtIFNvdXJjZSBvcGVyYXRvciBvY2N1cnJlbmNlLlxuICAgKiBAcmV0dXJucyB7RXhwcmVzc2lvbn0gQWRhcHRlZCBzZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgYmluYXJ5KG5vZGUsIGludGVudCwgbGVmdCwgcmlnaHQsIG9wZXJhdG9yKSB7XG4gICAgY29uc3QgZXhwcmVzc2lvbiA9IC8qKiBAdHlwZSB7RXhwcmVzc2lvbn0gKi8gKHdpdGhBZGFwdGVkT3BlcmF0aW9uKHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IFwiQmluYXJ5RXhwcmVzc2lvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgbGVmdCwgcmlnaHR9LFxuICAgICAge29wZXJhdG9yOiB0aGlzLmxvY2F0aW9uKG9wZXJhdG9yKX0pLCAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL29wZXJhdG9ycy5qc1wiKS5BZGFwdGVkT3BlcmF0aW9ufSAqLyAoaW50ZW50KSkpXG5cbiAgICB0aGlzLm9wZXJhdGlvbnMuc2V0KGV4cHJlc3Npb24sIHtub2RlOiBvcGVyYXRvciwgc3BlbGxpbmc6IHRoaXMudGV4dChvcGVyYXRvcil9KVxuICAgIHJldHVybiBleHByZXNzaW9uXG4gIH1cblxuICAvKipcbiAgICogQWRhcHRzIG9uZSB0eXBlZCB1bmFyeSBvcGVyYXRvci5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gV2hvbGUgZXhwcmVzc2lvbiBub2RlLlxuICAgKiBAcGFyYW0ge1wiTmVnYXRlXCIgfCBcIk5vdFwifSBpbnRlbnQgLSBTaGFyZWQgb3BlcmF0b3IgaW50ZW50LlxuICAgKiBAcGFyYW0ge0V4cHJlc3Npb259IG9wZXJhbmQgLSBDb252ZXJ0ZWQgb3BlcmFuZC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBvcGVyYXRvciAtIFNvdXJjZSBvcGVyYXRvciBvY2N1cnJlbmNlLlxuICAgKiBAcmV0dXJucyB7RXhwcmVzc2lvbn0gQWRhcHRlZCBzZW1hbnRpYyBleHByZXNzaW9uLlxuICAgKi9cbiAgdW5hcnkobm9kZSwgaW50ZW50LCBvcGVyYW5kLCBvcGVyYXRvcikge1xuICAgIGNvbnN0IGV4cHJlc3Npb24gPSAvKiogQHR5cGUge0V4cHJlc3Npb259ICovICh3aXRoQWRhcHRlZE9wZXJhdGlvbih3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgb3BlcmFuZH0sXG4gICAgICB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ob3BlcmF0b3IpfSksIGludGVudCkpXG5cbiAgICB0aGlzLm9wZXJhdGlvbnMuc2V0KGV4cHJlc3Npb24sIHtub2RlOiBvcGVyYXRvciwgc3BlbGxpbmc6IHRoaXMudGV4dChvcGVyYXRvcil9KVxuICAgIHJldHVybiBleHByZXNzaW9uXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBzdGF0ZW1lbnQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIFN0YXRlbWVudCBub2RlLlxuICAgKiBAcmV0dXJucyB7U3RhdGVtZW50fSBTZW1hbnRpYyBzdGF0ZW1lbnQuXG4gICAqL1xuICBzdGF0ZW1lbnQobm9kZSkge1xuICAgIGNvbnN0IGxvY2F0aW9uID0gdGhpcy5sb2NhdGlvbihub2RlKVxuICAgIGNvbnN0IHBhcnRzID0gdGhpcy5wYXJ0cyhub2RlKVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcInZhcmlhYmxlX2RlY2xhcmF0aW9uXCIpIHtcbiAgICAgIGlmIChbXCJjb25zdFwiLCBcInZhclwiXS5pbmNsdWRlcyhwYXJ0c1swXT8udHlwZSkpIHtcbiAgICAgICAgY29uc3QgdHlwZU5vZGUgPSBub2RlLmNoaWxkcmVuLmZpbmQoKHtmaWVsZH0pID0+IGZpZWxkID09IFwidHlwZVwiKT8ubm9kZVxuXG4gICAgICAgIGlmICghdHlwZU5vZGUpIHJldHVybiBtaXNzaW5nVHlwZShcInppZ1wiLCBcImxvY2FsXCIsIGxvY2F0aW9uKVxuICAgICAgICBjb25zdCBuYW1lID0gcGFydHNbMV1cbiAgICAgICAgY29uc3QgdmFsdWUgPSBwYXJ0c1s1XVxuXG4gICAgICAgIHRoaXMuc2hhcGUobm9kZSwgW3BhcnRzWzBdLCBuYW1lLCBcIjpcIiwgdHlwZU5vZGUsIFwiPVwiLCB2YWx1ZSwgXCI7XCJdKVxuICAgICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJMb2NhbERlY2xhcmF0aW9uXCIsIGxvY2F0aW9uLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobmFtZSksIHR5cGU6IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHRoaXMudHlwZSh0eXBlTm9kZSkpLCBtdXRhYmxlOiBwYXJ0c1swXS50eXBlID09IFwidmFyXCIsXG4gICAgICAgICAgaW5pdGlhbGl6ZXI6IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSl9LCB7bmFtZTogdGhpcy5sb2NhdGlvbihuYW1lKSwgb3BlcmF0b3I6IHRoaXMubG9jYXRpb24ocGFydHNbNF0pfSlcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhcmdldE5vZGUgPSBwYXJ0c1swXVxuICAgICAgY29uc3QgdmFsdWUgPSBwYXJ0c1syXVxuXG4gICAgICB0aGlzLnNoYXBlKG5vZGUsIFt0YXJnZXROb2RlLCBcIj1cIiwgdmFsdWUsIFwiO1wiXSlcbiAgICAgIGNvbnN0IHRhcmdldCA9IHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbih0YXJnZXROb2RlKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKHRhcmdldE5vZGUpfSwge25hbWU6IHRoaXMubG9jYXRpb24odGFyZ2V0Tm9kZSl9KVxuXG4gICAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJBc3NpZ25tZW50U3RhdGVtZW50XCIsIGxvY2F0aW9uLCB0YXJnZXQsIGV4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbih2YWx1ZSl9LCB7b3BlcmF0b3I6IHRoaXMubG9jYXRpb24ocGFydHNbMV0pfSlcbiAgICB9XG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImlmX3N0YXRlbWVudFwiKSByZXR1cm4gdGhpcy5jb25kaXRpb25hbChub2RlKVxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJleHByZXNzaW9uX3N0YXRlbWVudFwiKSB0aGlzLmZhaWwobm9kZSwgXCJleHBsaWNpdCBzdGF0ZW1lbnQgcmVxdWlyZWRcIilcbiAgICBjb25zdCBleHByZXNzaW9uID0gcGFydHNbMF1cblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW2V4cHJlc3Npb24sIFwiO1wiXSlcbiAgICBpZiAoZXhwcmVzc2lvbi50eXBlID09IFwicmV0dXJuX2V4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgcmV0dXJuZWQgPSB0aGlzLnBhcnRzKGV4cHJlc3Npb24pXG5cbiAgICAgIGlmIChyZXR1cm5lZC5sZW5ndGggPT0gMSkge1xuICAgICAgICB0aGlzLnNoYXBlKGV4cHJlc3Npb24sIFtcInJldHVyblwiXSlcbiAgICAgICAgcmV0dXJuIHtraW5kOiBcIlJldHVyblN0YXRlbWVudFwiLCBsb2NhdGlvbn1cbiAgICAgIH1cbiAgICAgIHRoaXMuc2hhcGUoZXhwcmVzc2lvbiwgW1wicmV0dXJuXCIsIHJldHVybmVkWzFdXSlcbiAgICAgIHJldHVybiB7a2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIiwgbG9jYXRpb24sIGV4cHJlc3Npb246IHRoaXMuZXhwcmVzc2lvbihyZXR1cm5lZFsxXSl9XG4gICAgfVxuICAgIGlmIChleHByZXNzaW9uLnR5cGUgIT0gXCJjYWxsX2V4cHJlc3Npb25cIikgdGhpcy5mYWlsKGV4cHJlc3Npb24sIFwiZGlyZWN0IHZvaWQgY2FsbCBzdGF0ZW1lbnQgcmVxdWlyZWRcIilcbiAgICBjb25zdCBjYWxsID0gdGhpcy5jYWxsKGV4cHJlc3Npb24pXG4gICAgY29uc3QgbmFtZSA9IHRoaXMudGV4dChjYWxsLm5hbWUpXG5cbiAgICBpZiAoL15zZW1hbnRpZm9sZF9wcmludF8oPzppbnRlZ2VyfGJvb2xlYW58c3RyaW5nKSQvdS50ZXN0KG5hbWUpKSB7XG4gICAgICBpZiAoY2FsbC5uYW1lLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgY2FsbC5hcmd1bWVudHMubGVuZ3RoICE9IDEpIHRoaXMuZmFpbChleHByZXNzaW9uLCBcImV4YWN0IHByaW50IGhlbHBlciBjYWxsIHJlcXVpcmVkXCIpXG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiUHJpbnRTdGF0ZW1lbnRcIiksIGxvY2F0aW9uLCBleHByZXNzaW9uOiB0aGlzLmV4cHJlc3Npb24oY2FsbC5hcmd1bWVudHNbMF0pfVxuXG4gICAgICB0aGlzLnByaW50cy5zZXQoc3RhdGVtZW50LCB7bm9kZTogY2FsbC5uYW1lLCB0eXBlOiBuYW1lLnNsaWNlKFwic2VtYW50aWZvbGRfcHJpbnRfXCIubGVuZ3RoKX0pXG4gICAgICByZXR1cm4gc3RhdGVtZW50XG4gICAgfVxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5leHByZXNzaW9uKGV4cHJlc3Npb24pXG5cbiAgICBpZiAodmFsdWUua2luZCAhPSBcIkNhbGxFeHByZXNzaW9uXCIpIHRoaXMuZmFpbChleHByZXNzaW9uLCBcImRpcmVjdCB2b2lkIGNhbGwgc3RhdGVtZW50IHJlcXVpcmVkXCIpXG4gICAgcmV0dXJuIHtraW5kOiBcIkV4cHJlc3Npb25TdGF0ZW1lbnRcIiwgbG9jYXRpb24sIGV4cHJlc3Npb246IHZhbHVlfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIG9uZSBzdHJpY3QgQm9vbGVhbiBjb25kaXRpb25hbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gSWYtc3RhdGVtZW50IG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5JZlN0YXRlbWVudH0gU2VtYW50aWMgY29uZGl0aW9uYWwuXG4gICAqL1xuICBjb25kaXRpb25hbChub2RlKSB7XG4gICAgY29uc3QgY29uZGl0aW9uID0gdGhpcy5maWVsZChub2RlLCBcImNvbmRpdGlvblwiKVxuICAgIGNvbnN0IGJvZHkgPSB0aGlzLmZpZWxkKG5vZGUsIFwiYm9keVwiKVxuICAgIGNvbnN0IGFsdGVybmF0aXZlID0gdGhpcy5wYXJ0cyhub2RlKS5maW5kKGNoaWxkID0+IGNoaWxkLnR5cGUgPT0gXCJlbHNlX2NsYXVzZVwiKVxuXG4gICAgdGhpcy5zaGFwZShub2RlLCBbXCJpZlwiLCBcIihcIiwgY29uZGl0aW9uLCBcIilcIiwgYm9keSwgLi4uKGFsdGVybmF0aXZlID8gW2FsdGVybmF0aXZlXSA6IFtdKV0pXG4gICAgY29uc3Qgc3RhdGVtZW50ID0ge2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklmU3RhdGVtZW50XCIpLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihub2RlKSwgY29uZGl0aW9uOiB0aGlzLmV4cHJlc3Npb24oY29uZGl0aW9uKSwgY29uc2VxdWVudDogdGhpcy5ibG9ja0V4cHJlc3Npb24oYm9keSl9XG5cbiAgICBpZiAoIWFsdGVybmF0aXZlKSByZXR1cm4gc3RhdGVtZW50XG4gICAgY29uc3QgYnJhbmNoID0gdGhpcy5maWVsZChhbHRlcm5hdGl2ZSwgXCJhbHRlcm5hdGl2ZVwiKVxuXG4gICAgdGhpcy5zaGFwZShhbHRlcm5hdGl2ZSwgW1wiZWxzZVwiLCBicmFuY2hdKVxuICAgIGlmIChicmFuY2gudHlwZSAhPSBcImxhYmVsZWRfc3RhdGVtZW50XCIpIHRoaXMuZmFpbChicmFuY2gsIFwiYnJhY2VkIGVsc2UgYmxvY2sgcmVxdWlyZWRcIilcbiAgICBjb25zdCBibG9jayA9IHRoaXMucGFydHMoYnJhbmNoKVswXVxuXG4gICAgdGhpcy5zaGFwZShicmFuY2gsIFtibG9ja10pXG4gICAgcmV0dXJuIHsuLi5zdGF0ZW1lbnQsIGFsdGVybmF0ZTogdGhpcy5ibG9jayhibG9jayl9XG4gIH1cblxuICAvKipcbiAgICogVW53cmFwcyBvbmUgYnJhY2VkIGNvbmRpdGlvbmFsIGJsb2NrIGV4cHJlc3Npb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEJsb2NrLWV4cHJlc3Npb24gbm9kZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAgICovXG4gIGJsb2NrRXhwcmVzc2lvbihub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPSBcImJsb2NrX2V4cHJlc3Npb25cIikgdGhpcy5mYWlsKG5vZGUsIFwiYnJhY2VkIGNvbmRpdGlvbmFsIGJsb2NrIHJlcXVpcmVkXCIpXG4gICAgY29uc3QgYmxvY2sgPSB0aGlzLnBhcnRzKG5vZGUpWzBdXG5cbiAgICB0aGlzLnNoYXBlKG5vZGUsIFtibG9ja10pXG4gICAgcmV0dXJuIHRoaXMuYmxvY2soYmxvY2spXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGxleGljYWwgYmxvY2sgd2hpbGUgY29uc3VtaW5nIGV4YWN0IGNvbXBpbGVyIHNjYWZmb2xkcy5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQmxvY2sgbm9kZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IFtza2lwXSAtIEZpeGVkIGxlYWRpbmcgZ2VuZXJhdGVkIHN0YXRlbWVudHMgdG8gb21pdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5QYXJhbWV0ZXJbXX0gW3BhcmFtZXRlcnNdIC0gUGFyYW1ldGVycyByZXF1aXJpbmcgc2NhZmZvbGQgY2hlY2tzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IFNlbWFudGljIGJsb2NrLlxuICAgKi9cbiAgYmxvY2sobm9kZSwgc2tpcCA9IDAsIHBhcmFtZXRlcnMgPSBbXSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJibG9ja1wiKSB0aGlzLmZhaWwobm9kZSwgXCJicmFjZWQgYmxvY2sgcmVxdWlyZWRcIilcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW1wie1wiLCAuLi5wYXJ0cy5zbGljZSgxLCAtMSksIFwifVwiXSlcbiAgICBjb25zdCBzb3VyY2VTdGF0ZW1lbnRzID0gdGhpcy5zaWduaWZpY2FudChub2RlKS5zbGljZSgxICsgc2tpcCwgLTEpXG4gICAgcmV0dXJuIHtraW5kOiBcIkJsb2NrXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBzdGF0ZW1lbnRzOiB0aGlzLmdlbmVyYXRlZFxuICAgICAgPyB0aGlzLmdlbmVyYXRlZFN0YXRlbWVudHMoc291cmNlU3RhdGVtZW50cywgcGFyYW1ldGVycylcbiAgICAgIDogdGhpcy5kaXJlY3RTdGF0ZW1lbnRzKHNvdXJjZVN0YXRlbWVudHMsIHBhcmFtZXRlcnMpfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbnZlcnRzIHRoZSBsZWdhY3kgZGlyZWN0IHN0YXRlbWVudCBzaGFwZSB3aGVuIGRpYWdub3NpbmcgYSBtaXNzaW5nIGdlbmVyYXRlZCBtYXJrZXIuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZVtdfSBzb3VyY2VTdGF0ZW1lbnRzIC0gT3JkZXJlZCBkaXJlY3QgY2hpbGRyZW4uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuUGFyYW1ldGVyW119IHBhcmFtZXRlcnMgLSBGdW5jdGlvbiBwYXJhbWV0ZXJzLlxuICAgKiBAcmV0dXJucyB7U3RhdGVtZW50W119IFNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBkaXJlY3RTdGF0ZW1lbnRzKHNvdXJjZVN0YXRlbWVudHMsIHBhcmFtZXRlcnMpIHtcbiAgICBsZXQgY3Vyc29yID0gMFxuXG4gICAgZm9yIChjb25zdCBwYXJhbWV0ZXIgb2YgcGFyYW1ldGVycykge1xuICAgICAgY29uc3Qga2luZCA9IHNvdXJjZVN0YXRlbWVudHNbY3Vyc29yXSA/IHRoaXMudXNlU2NhZmZvbGQoc291cmNlU3RhdGVtZW50c1tjdXJzb3JdLCBwYXJhbWV0ZXIubmFtZSkgOiB1bmRlZmluZWRcblxuICAgICAgdGhpcy5zY2FmZm9sZHMuc2V0KHBhcmFtZXRlciwga2luZCA/PyBcIm5vbmVcIilcbiAgICAgIGlmIChraW5kKSBjdXJzb3IgKz0gMVxuICAgIH1cbiAgICAvKiogQHR5cGUge1N0YXRlbWVudFtdfSAqL1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXVxuXG4gICAgd2hpbGUgKGN1cnNvciA8IHNvdXJjZVN0YXRlbWVudHMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB0aGlzLnN0YXRlbWVudChzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0pXG5cbiAgICAgIHN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpXG4gICAgICBjdXJzb3IgKz0gMVxuICAgICAgaWYgKHN0YXRlbWVudC5raW5kID09IFwiTG9jYWxEZWNsYXJhdGlvblwiKSB7XG4gICAgICAgIGNvbnN0IGtpbmQgPSBzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0gPyB0aGlzLnVzZVNjYWZmb2xkKHNvdXJjZVN0YXRlbWVudHNbY3Vyc29yXSwgc3RhdGVtZW50Lm5hbWUpIDogdW5kZWZpbmVkXG5cbiAgICAgICAgdGhpcy5zY2FmZm9sZHMuc2V0KHN0YXRlbWVudCwga2luZCA/PyBcIm5vbmVcIilcbiAgICAgICAgaWYgKGtpbmQpIGN1cnNvciArPSAxXG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZW1lbnRzXG4gIH1cblxuICAvKipcbiAgICogUmVjb25zdHJ1Y3RzIGNvbXBsZXRlIGdlbmVyYXRlZCBzdGF0ZW1lbnQgcmVnaW9ucyBiZWZvcmUgY2Fub25pY2FsIHdob2xlLUNTVCB2ZXJpZmljYXRpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZVtdfSBzb3VyY2VTdGF0ZW1lbnRzIC0gU2lnbmlmaWNhbnQgZGlyZWN0IGJsb2NrIGNoaWxkcmVuLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlBhcmFtZXRlcltdfSBwYXJhbWV0ZXJzIC0gRnVuY3Rpb24gcGFyYW1ldGVycy5cbiAgICogQHJldHVybnMge1N0YXRlbWVudFtdfSBSZWNvbnN0cnVjdGVkIHNlbWFudGljIHN0YXRlbWVudHMuXG4gICAqL1xuICBnZW5lcmF0ZWRTdGF0ZW1lbnRzKHNvdXJjZVN0YXRlbWVudHMsIHBhcmFtZXRlcnMpIHtcbiAgICAvKiogQHR5cGUge1N0YXRlbWVudFtdfSAqL1xuICAgIGNvbnN0IHN0YXRlbWVudHMgPSBbXVxuICAgIGxldCBjdXJzb3IgPSAwXG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XG4gICAgICBjb25zdCBraW5kID0gc291cmNlU3RhdGVtZW50c1tjdXJzb3JdID8gdGhpcy51c2VTY2FmZm9sZChzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0sIHBhcmFtZXRlci5uYW1lKSA6IHVuZGVmaW5lZFxuXG4gICAgICB0aGlzLnNjYWZmb2xkcy5zZXQocGFyYW1ldGVyLCBraW5kID8/IFwibm9uZVwiKVxuICAgICAgaWYgKGtpbmQpIGN1cnNvciArPSAxXG4gICAgfVxuICAgIHdoaWxlIChjdXJzb3IgPCBzb3VyY2VTdGF0ZW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29uc3QgYmVnaW4gPSBzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcisrXVxuICAgICAgY29uc3QgbWF0Y2ggPSBiZWdpbi50eXBlID09IFwiY29tbWVudFwiICYmXG4gICAgICAgIC9eXFwvXFwvIHNlbWFudGlmb2xkOm9yZGVyZWQtZXhwcmVzc2lvbjp6aWc6djEgYmVnaW4gKFswLTldezZ9KSAoWzAtOWEtZl17NjR9KSQvdS5leGVjKHRoaXMubWFya2VyKGJlZ2luKSlcblxuICAgICAgaWYgKCFtYXRjaCkgdGhpcy5mYWlsKGJlZ2luLCBcImNvbXBsZXRlIGdlbmVyYXRlZCBvcmRlcmVkIHN0YXRlbWVudCByZWdpb24gcmVxdWlyZWRcIilcbiAgICAgIGNvbnN0IG91dGVyRXhwcmVzc2lvbnMgPSB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zXG4gICAgICBjb25zdCBvdXRlck5hbWVzID0gdGhpcy50ZW1wb3JhcnlOYW1lc1xuXG4gICAgICB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zID0gbmV3IE1hcCgpXG4gICAgICB0aGlzLnRlbXBvcmFyeU5hbWVzID0gbmV3IFNldCgpXG4gICAgICB3aGlsZSAoY3Vyc29yIDwgc291cmNlU3RhdGVtZW50cy5sZW5ndGggJiYgdGhpcy50ZW1wb3JhcnlEZWNsYXJhdGlvbihzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0pKSB7XG4gICAgICAgIGN1cnNvciA9IHRoaXMucmVhZFRlbXBvcmFyeShzb3VyY2VTdGF0ZW1lbnRzLCBjdXJzb3IpXG4gICAgICB9XG4gICAgICBjb25zdCBjb25zdW1lciA9IHNvdXJjZVN0YXRlbWVudHNbY3Vyc29yKytdXG5cbiAgICAgIGlmICghY29uc3VtZXIpIHRoaXMuZmFpbChiZWdpbiwgXCJtaXNzaW5nIGdlbmVyYXRlZCBvcmRlcmVkIGNvbnN1bWVyXCIpXG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB0aGlzLnN0YXRlbWVudChjb25zdW1lcilcblxuICAgICAgaWYgKHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnMuc2l6ZSAhPSAwKSB0aGlzLmZhaWwoY29uc3VtZXIsIFwidW5jb25zdW1lZCBnZW5lcmF0ZWQgb3JkZXJlZCB0ZW1wb3JhcnlcIilcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICBjb25zdCBraW5kID0gc291cmNlU3RhdGVtZW50c1tjdXJzb3JdID8gdGhpcy51c2VTY2FmZm9sZChzb3VyY2VTdGF0ZW1lbnRzW2N1cnNvcl0sIHN0YXRlbWVudC5uYW1lKSA6IHVuZGVmaW5lZFxuXG4gICAgICAgIHRoaXMuc2NhZmZvbGRzLnNldChzdGF0ZW1lbnQsIGtpbmQgPz8gXCJub25lXCIpXG4gICAgICAgIGlmIChraW5kKSBjdXJzb3IgKz0gMVxuICAgICAgfVxuICAgICAgY29uc3QgZW5kID0gc291cmNlU3RhdGVtZW50c1tjdXJzb3IrK11cblxuICAgICAgaWYgKCFlbmQgfHwgZW5kLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgdGhpcy5tYXJrZXIoZW5kKSAhPVxuICAgICAgICBgLy8gc2VtYW50aWZvbGQ6b3JkZXJlZC1leHByZXNzaW9uOnppZzp2MSBlbmQgJHttYXRjaFsxXX0gJHttYXRjaFsyXX1gKSB0aGlzLmZhaWwoZW5kID8/IGJlZ2luLCBcImdlbmVyYXRlZCBvcmRlcmVkIG1hcmtlciBwYWlyXCIpXG4gICAgICB0aGlzLnRlbXBvcmFyeUV4cHJlc3Npb25zID0gb3V0ZXJFeHByZXNzaW9uc1xuICAgICAgdGhpcy50ZW1wb3JhcnlOYW1lcyA9IG91dGVyTmFtZXNcbiAgICAgIHN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpXG4gICAgfVxuICAgIHJldHVybiBzdGF0ZW1lbnRzXG4gIH1cblxuICAvKipcbiAgICogSWRlbnRpZmllcyBhIHJlc2VydmVkIG9yZGVyZWQgdGVtcG9yYXJ5IGRlY2xhcmF0aW9uIGF0IHRoZSBjdXJyZW50IHJlZ2lvbiBsZXZlbC5cbiAgICogQHBhcmFtIHtDc3ROb2RlfSBub2RlIC0gQ2FuZGlkYXRlIGRpcmVjdCBjaGlsZC5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgaXQgZGVjbGFyZXMgYSByZXNlcnZlZCBvcmRlcmVkIHRlbXBvcmFyeS5cbiAgICovXG4gIHRlbXBvcmFyeURlY2xhcmF0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIHJldHVybiBub2RlLnR5cGUgPT0gXCJ2YXJpYWJsZV9kZWNsYXJhdGlvblwiICYmIFtcImNvbnN0XCIsIFwidmFyXCJdLmluY2x1ZGVzKHBhcnRzWzBdPy50eXBlKSAmJlxuICAgICAgcGFydHNbMV0/LnR5cGUgPT0gXCJpZGVudGlmaWVyXCIgJiYgdGhpcy50ZXh0KHBhcnRzWzFdKS5zdGFydHNXaXRoKFwic2VtYW50aWZvbGRfb3JkZXJlZF9cIilcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBhbmRzIG9uZSB0eXBlZCBvcmRlcmVkIHRlbXBvcmFyeSBhbmQgYW4gb3B0aW9uYWwgY29uZGl0aW9uYWwgQm9vbGVhbiBSSFMuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZVtdfSBub2RlcyAtIEN1cnJlbnQgcmVnaW9uIGNoaWxkcmVuLlxuICAgKiBAcGFyYW0ge251bWJlcn0gY3Vyc29yIC0gVGVtcG9yYXJ5IGRlY2xhcmF0aW9uIHBvc2l0aW9uLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSBOZXh0IHVuY29uc3VtZWQgcG9zaXRpb24uXG4gICAqL1xuICByZWFkVGVtcG9yYXJ5KG5vZGVzLCBjdXJzb3IpIHtcbiAgICBjb25zdCBub2RlID0gbm9kZXNbY3Vyc29yKytdXG4gICAgY29uc3QgcGFydHMgPSB0aGlzLnBhcnRzKG5vZGUpXG4gICAgY29uc3QgbmFtZU5vZGUgPSBwYXJ0c1sxXVxuICAgIGNvbnN0IG5hbWUgPSB0aGlzLnRleHQobmFtZU5vZGUpXG4gICAgY29uc3QgdHlwZU5vZGUgPSB0aGlzLmZpZWxkKG5vZGUsIFwidHlwZVwiKVxuICAgIGNvbnN0IHZhbHVlID0gcGFydHNbNV1cblxuICAgIHRoaXMuc2hhcGUobm9kZSwgW3BhcnRzWzBdLCBuYW1lTm9kZSwgXCI6XCIsIHR5cGVOb2RlLCBcIj1cIiwgdmFsdWUsIFwiO1wiXSlcbiAgICB0aGlzLnR5cGUodHlwZU5vZGUpXG4gICAgaWYgKCEvXnNlbWFudGlmb2xkX29yZGVyZWRfWzAtOV17Nn0kL3UudGVzdChuYW1lKSB8fCB0aGlzLnRlbXBvcmFyeU5hbWVzPy5oYXMobmFtZSkpIHtcbiAgICAgIHRoaXMuZmFpbChuYW1lTm9kZSwgXCJnZW5lcmF0ZWQgb3JkZXJlZCB0ZW1wb3JhcnkgZGVjbGFyYXRpb25cIilcbiAgICB9XG4gICAgdGhpcy50ZW1wb3JhcnlOYW1lcz8uYWRkKG5hbWUpXG4gICAgbGV0IGV4cHJlc3Npb24gPSB0aGlzLmV4cHJlc3Npb24odmFsdWUpXG4gICAgY29uc3QgYnJhbmNoID0gbm9kZXNbY3Vyc29yXVxuXG4gICAgaWYgKGJyYW5jaCAmJiB0aGlzLnNob3J0Q2lyY3VpdEJyYW5jaChicmFuY2gsIG5hbWUpKSB7XG4gICAgICBjb25zdCBjb25kaXRpb24gPSB0aGlzLmZpZWxkKGJyYW5jaCwgXCJjb25kaXRpb25cIilcbiAgICAgIGNvbnN0IGJvZHkgPSB0aGlzLmZpZWxkKGJyYW5jaCwgXCJib2R5XCIpXG4gICAgICBjb25zdCBjb25kaXRpb25QYXJ0cyA9IHRoaXMucGFydHMoY29uZGl0aW9uKVxuICAgICAgY29uc3QgaXNPciA9IGNvbmRpdGlvblBhcnRzWzBdPy50eXBlID09IFwiIVwiXG4gICAgICBjb25zdCB0YXJnZXQgPSBpc09yID8gdGhpcy5maWVsZChjb25kaXRpb24sIGNvbmRpdGlvbi50eXBlID09IFwidW5hcnlfZXhwcmVzc2lvblwiID8gXCJhcmd1bWVudFwiIDogXCJva1wiKSA6IGNvbmRpdGlvblxuXG4gICAgICB0aGlzLnNoYXBlKGJyYW5jaCwgW1wiaWZcIiwgXCIoXCIsIGNvbmRpdGlvbiwgXCIpXCIsIGJvZHldKVxuICAgICAgaWYgKHRhcmdldC50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IHRoaXMudGV4dCh0YXJnZXQpICE9IG5hbWUpIHRoaXMuZmFpbCh0YXJnZXQsIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgdGVtcG9yYXJ5IHRlc3RcIilcbiAgICAgIGlmIChpc09yKSB0aGlzLnNoYXBlKGNvbmRpdGlvbiwgW2NvbmRpdGlvblBhcnRzWzBdLCB0YXJnZXRdKVxuICAgICAgaWYgKGlzT3IgJiYgY29uZGl0aW9uUGFydHNbMF0/LnR5cGUgIT0gXCIhXCIpIHRoaXMuZmFpbChjb25kaXRpb25QYXJ0c1swXSA/PyBjb25kaXRpb24sIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgbmVnYXRpb25cIilcbiAgICAgIGlmIChib2R5LnR5cGUgIT0gXCJibG9ja19leHByZXNzaW9uXCIpIHRoaXMuZmFpbChib2R5LCBcImdlbmVyYXRlZCBzaG9ydC1jaXJjdWl0IGJsb2NrXCIpXG4gICAgICBjb25zdCBibG9jayA9IHRoaXMucGFydHMoYm9keSlbMF1cblxuICAgICAgdGhpcy5zaGFwZShib2R5LCBbYmxvY2tdKVxuICAgICAgaWYgKGJsb2NrLnR5cGUgIT0gXCJibG9ja1wiKSB0aGlzLmZhaWwoYmxvY2ssIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgYmxvY2tcIilcbiAgICAgIGNvbnN0IGluc2lkZSA9IHRoaXMuc2lnbmlmaWNhbnQoYmxvY2spLnNsaWNlKDEsIC0xKVxuICAgICAgbGV0IG9mZnNldCA9IDBcblxuICAgICAgd2hpbGUgKG9mZnNldCA8IGluc2lkZS5sZW5ndGggJiYgdGhpcy50ZW1wb3JhcnlEZWNsYXJhdGlvbihpbnNpZGVbb2Zmc2V0XSkpIG9mZnNldCA9IHRoaXMucmVhZFRlbXBvcmFyeShpbnNpZGUsIG9mZnNldClcbiAgICAgIGlmIChvZmZzZXQgIT0gaW5zaWRlLmxlbmd0aCAtIDEpIHRoaXMuZmFpbChibG9jaywgXCJnZW5lcmF0ZWQgc2hvcnQtY2lyY3VpdCBmaW5hbCBhc3NpZ25tZW50XCIpXG4gICAgICBjb25zdCBhc3NpZ25tZW50ID0gaW5zaWRlW29mZnNldF1cbiAgICAgIGNvbnN0IGFzc2lnbm1lbnRQYXJ0cyA9IHRoaXMucGFydHMoYXNzaWdubWVudClcbiAgICAgIGNvbnN0IGxlZnQgPSBhc3NpZ25tZW50UGFydHNbMF1cbiAgICAgIGNvbnN0IHJpZ2h0ID0gYXNzaWdubWVudFBhcnRzWzJdXG5cbiAgICAgIHRoaXMuc2hhcGUoYXNzaWdubWVudCwgW2xlZnQsIFwiPVwiLCByaWdodCwgXCI7XCJdKVxuICAgICAgaWYgKGxlZnQudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCB0aGlzLnRleHQobGVmdCkgIT0gbmFtZSkgdGhpcy5mYWlsKGxlZnQsIFwiZ2VuZXJhdGVkIHNob3J0LWNpcmN1aXQgcmVzdWx0IHdyaXRlXCIpXG4gICAgICBpZiAocmlnaHQudHlwZSAhPSBcImJpbmFyeV9leHByZXNzaW9uXCIpIHRoaXMuZmFpbChyaWdodCwgXCJnZW5lcmF0ZWQgc2hvcnQtY2lyY3VpdCByZXN1bHQgZXhwcmVzc2lvblwiKVxuICAgICAgY29uc3QgcmVwZWF0ZWQgPSB0aGlzLmZpZWxkKHJpZ2h0LCBcImxlZnRcIilcbiAgICAgIGNvbnN0IG9wZXJhbmQgPSB0aGlzLmZpZWxkKHJpZ2h0LCBcInJpZ2h0XCIpXG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMuZmllbGQocmlnaHQsIFwib3BlcmF0b3JcIilcbiAgICAgIGNvbnN0IHNwZWxsaW5nID0gaXNPciA/IFwib3JcIiA6IFwiYW5kXCJcblxuICAgICAgdGhpcy5zaGFwZShyaWdodCwgW3JlcGVhdGVkLCBzcGVsbGluZywgb3BlcmFuZF0pXG4gICAgICBpZiAocmVwZWF0ZWQudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCB0aGlzLnRleHQocmVwZWF0ZWQpICE9IG5hbWUpIHRoaXMuZmFpbChyZXBlYXRlZCwgXCJnZW5lcmF0ZWQgc2hvcnQtY2lyY3VpdCBjb25zdW1lZCB2YWx1ZVwiKVxuICAgICAgZXhwcmVzc2lvbiA9IHRoaXMuYmluYXJ5KHJpZ2h0LCBpc09yID8gXCJPclwiIDogXCJBbmRcIiwgZXhwcmVzc2lvbiwgdGhpcy5leHByZXNzaW9uKG9wZXJhbmQpLCBvcGVyYXRvcilcbiAgICAgIGN1cnNvciArPSAxXG4gICAgfVxuICAgIHRoaXMudGVtcG9yYXJ5RXhwcmVzc2lvbnM/LnNldChuYW1lLCBleHByZXNzaW9uKVxuICAgIHJldHVybiBjdXJzb3JcbiAgfVxuXG4gIC8qKlxuICAgKiBEaXN0aW5ndWlzaGVzIGFuIGludGVybmFsIGNvbmRpdGlvbmFsIFJIUyBmcm9tIHRoZSBmb2xsb3dpbmcgc2VtYW50aWMgYGlmYCBjb25zdW1lciB1c2luZyBvbmx5IGRpcmVjdCBDU1Qgc3RydWN0dXJlLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgY29uZGl0aW9uYWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gT3JkZXJlZCBCb29sZWFuIHJlc3VsdCBuYW1lLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgbm9kZSBoYXMgdGhlIGNvbXBsZXRlIG91dGVyIHNoYXBlIG9mIGEgc2hvcnQtY2lyY3VpdCB1cGRhdGUuXG4gICAqL1xuICBzaG9ydENpcmN1aXRCcmFuY2gobm9kZSwgbmFtZSkge1xuICAgIGlmIChub2RlLnR5cGUgIT0gXCJpZl9zdGF0ZW1lbnRcIiB8fCB0aGlzLnBhcnRzKG5vZGUpLnNvbWUoY2hpbGQgPT4gY2hpbGQudHlwZSA9PSBcImVsc2VfY2xhdXNlXCIpKSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBib2R5ID0gbm9kZS5jaGlsZHJlbi5maW5kKCh7ZmllbGR9KSA9PiBmaWVsZCA9PSBcImJvZHlcIik/Lm5vZGVcblxuICAgIGlmIChib2R5Py50eXBlICE9IFwiYmxvY2tfZXhwcmVzc2lvblwiKSByZXR1cm4gZmFsc2VcbiAgICBjb25zdCBibG9jayA9IHRoaXMucGFydHMoYm9keSlbMF1cblxuICAgIGlmIChibG9jaz8udHlwZSAhPSBcImJsb2NrXCIpIHJldHVybiBmYWxzZVxuICAgIGNvbnN0IGluc2lkZSA9IHRoaXMuc2lnbmlmaWNhbnQoYmxvY2spLnNsaWNlKDEsIC0xKVxuICAgIGNvbnN0IGZpbmFsID0gaW5zaWRlLmF0KC0xKVxuICAgIGNvbnN0IGZpbmFsUGFydHMgPSBmaW5hbCA/IHRoaXMucGFydHMoZmluYWwpIDogW11cblxuICAgIHJldHVybiBpbnNpZGUubGVuZ3RoID4gMCAmJiAhaW5zaWRlLnNvbWUoY2hpbGQgPT4gY2hpbGQudHlwZSA9PSBcImNvbW1lbnRcIikgJiYgZmluYWw/LnR5cGUgPT0gXCJ2YXJpYWJsZV9kZWNsYXJhdGlvblwiICYmXG4gICAgICBmaW5hbFBhcnRzWzBdPy50eXBlID09IFwiaWRlbnRpZmllclwiICYmIHRoaXMudGV4dChmaW5hbFBhcnRzWzBdKSA9PSBuYW1lICYmIGZpbmFsUGFydHNbMV0/LnR5cGUgPT0gXCI9XCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvZ25pemVzIG9uZSBleGFjdCBnZW5lcmF0ZWQgdW51c2VkIG9yIHVubXV0YXRlZCBiaW5kaW5nIHNjYWZmb2xkLlxuICAgKiBAcGFyYW0ge0NzdE5vZGV9IG5vZGUgLSBDYW5kaWRhdGUgc3RhdGVtZW50IG5vZGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gQmluZGluZyBuYW1lLlxuICAgKiBAcmV0dXJucyB7XCJ1c2VcIiB8IFwiYWRkcmVzc1wiIHwgdW5kZWZpbmVkfSBTY2FmZm9sZCBmb3JtIHdoZW4gbWF0Y2hlZC5cbiAgICovXG4gIHVzZVNjYWZmb2xkKG5vZGUsIG5hbWUpIHtcbiAgICBjb25zdCBwYXJ0cyA9IHRoaXMucGFydHMobm9kZSlcblxuICAgIGlmIChub2RlLnR5cGUgIT0gXCJ2YXJpYWJsZV9kZWNsYXJhdGlvblwiIHx8IHBhcnRzLmxlbmd0aCAhPSA0IHx8IHBhcnRzWzBdLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHwgdGhpcy50ZXh0KHBhcnRzWzBdKSAhPSBcIl9cIiB8fCBwYXJ0c1sxXS50eXBlICE9IFwiPVwiIHx8IHBhcnRzWzNdLnR5cGUgIT0gXCI7XCIpIHJldHVybiB1bmRlZmluZWRcbiAgICBpZiAocGFydHNbMl0udHlwZSA9PSBcImlkZW50aWZpZXJcIiAmJiB0aGlzLnRleHQocGFydHNbMl0pID09IG5hbWUpIHJldHVybiBcInVzZVwiXG4gICAgaWYgKHBhcnRzWzJdLnR5cGUgPT0gXCJyZWZlcmVuY2VfZXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCByZWZlcmVuY2UgPSB0aGlzLnBhcnRzKHBhcnRzWzJdKVxuXG4gICAgICBpZiAocmVmZXJlbmNlLmxlbmd0aCA9PSAyICYmIHJlZmVyZW5jZVswXS50eXBlID09IFwiJlwiICYmIHJlZmVyZW5jZVsxXS50eXBlID09IFwiaWRlbnRpZmllclwiICYmIHRoaXMudGV4dChyZWZlcmVuY2VbMV0pID09IG5hbWUpIHJldHVybiBcImFkZHJlc3NcIlxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgb25lIGNhbm9uaWNhbCB0b3AtbGV2ZWwgc2VtYW50aWMgZnVuY3Rpb24uXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gbm9kZSAtIEZ1bmN0aW9uIGRlY2xhcmF0aW9uIG5vZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5GdW5jdGlvbkRlY2xhcmF0aW9ufSBTZW1hbnRpYyBmdW5jdGlvbi5cbiAgICovXG4gIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBjb25zdCBuYW1lID0gdGhpcy5maWVsZChub2RlLCBcIm5hbWVcIilcbiAgICBjb25zdCBwYXJhbWV0ZXJzID0gdGhpcy5wYXJ0cyhub2RlKS5maW5kKGNoaWxkID0+IGNoaWxkLnR5cGUgPT0gXCJwYXJhbWV0ZXJzXCIpXG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IHRoaXMuZmllbGQobm9kZSwgXCJ0eXBlXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobm9kZSwgXCJib2R5XCIpXG5cbiAgICBpZiAoIXBhcmFtZXRlcnMpIHRoaXMuZmFpbChub2RlLCBcInBhcmFtZXRlciBsaXN0IHJlcXVpcmVkXCIpXG4gICAgdGhpcy5zaGFwZShub2RlLCBbXCJmblwiLCBuYW1lLCBwYXJhbWV0ZXJzLCByZXR1cm5UeXBlLCBib2R5XSlcbiAgICBjb25zdCBwYXJhbWV0ZXJQYXJ0cyA9IHRoaXMucGFydHMocGFyYW1ldGVycylcbiAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSBwYXJhbWV0ZXJQYXJ0cy5zbGljZSgxLCAtMSkuZmlsdGVyKChfcGFydCwgaW5kZXgpID0+IGluZGV4ICUgMiA9PSAwKVxuXG4gICAgdGhpcy5zaGFwZShwYXJhbWV0ZXJzLCBbXCIoXCIsIC4uLmRlY2xhcmF0aW9ucy5mbGF0TWFwKChwYXJhbWV0ZXIsIGluZGV4KSA9PiBpbmRleCA/IFtcIixcIiwgcGFyYW1ldGVyXSA6IFtwYXJhbWV0ZXJdKSwgXCIpXCJdKVxuICAgIGNvbnN0IGNvbnZlcnRlZCA9IGRlY2xhcmF0aW9ucy5tYXAocGFyYW1ldGVyID0+IHtcbiAgICAgIGlmIChwYXJhbWV0ZXIudHlwZSAhPSBcInBhcmFtZXRlclwiKSB0aGlzLmZhaWwocGFyYW1ldGVyLCBcInJlcXVpcmVkIHR5cGVkIHBhcmFtZXRlclwiKVxuICAgICAgY29uc3QgcGFyYW1ldGVyTmFtZSA9IHRoaXMuZmllbGQocGFyYW1ldGVyLCBcIm5hbWVcIilcbiAgICAgIGNvbnN0IHR5cGUgPSB0aGlzLmZpZWxkKHBhcmFtZXRlciwgXCJ0eXBlXCIpXG5cbiAgICAgIHRoaXMuc2hhcGUocGFyYW1ldGVyLCBbcGFyYW1ldGVyTmFtZSwgXCI6XCIsIHR5cGVdKVxuICAgICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIlBhcmFtZXRlclwiKSwgbG9jYXRpb246IHRoaXMubG9jYXRpb24ocGFyYW1ldGVyKSwgbmFtZTogdGhpcy5pZGVudGlmaWVyKHBhcmFtZXRlck5hbWUpLCB0eXBlOiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9ICovICh0aGlzLnR5cGUodHlwZSkpfSwge25hbWU6IHRoaXMubG9jYXRpb24ocGFyYW1ldGVyTmFtZSl9KVxuICAgIH0pXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogXCJGdW5jdGlvbkRlY2xhcmF0aW9uXCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG5vZGUpLCBuYW1lOiB0aGlzLmlkZW50aWZpZXIobmFtZSksIHBhcmFtZXRlcnM6IGNvbnZlcnRlZCxcbiAgICAgIHJldHVyblR5cGU6IHRoaXMudHlwZShyZXR1cm5UeXBlLCB0cnVlKSwgYm9keTogdGhpcy5ibG9jayhib2R5LCAwLCBjb252ZXJ0ZWQpfSwge25hbWU6IHRoaXMubG9jYXRpb24obmFtZSl9KVxuICB9XG5cbiAgLyoqXG4gICAqIENvbXBhcmVzIGV2ZXJ5IG5vZGUsIHRva2VuLCBhbmQgZmllbGQgYWdhaW5zdCBjYW5vbmljYWwgZ2VuZXJhdGVkIHN1cHBvcnQuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gYWN0dWFsIC0gU291cmNlIHN1YnRyZWUuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gZXhwZWN0ZWQgLSBDYW5vbmljYWwgc3VidHJlZS5cbiAgICogQHBhcmFtIHtaaWdSZWFkZXJ9IGNhbm9uaWNhbCAtIFJlYWRlciBvd25pbmcgdGhlIGNhbm9uaWNhbCBzb3VyY2UuXG4gICAqL1xuICBjb21wYXJlVHJlZShhY3R1YWwsIGV4cGVjdGVkLCBjYW5vbmljYWwpIHtcbiAgICBpZiAoYWN0dWFsLnR5cGUgIT0gZXhwZWN0ZWQudHlwZSB8fCBhY3R1YWwubmFtZWQgIT0gZXhwZWN0ZWQubmFtZWQgfHwgYWN0dWFsLmV4dHJhICE9IGV4cGVjdGVkLmV4dHJhKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IG5vZGVcIilcbiAgICBjb25zdCBsZWZ0ID0gdGhpcy5zaWduaWZpY2FudChhY3R1YWwpXG4gICAgY29uc3QgcmlnaHQgPSBjYW5vbmljYWwuc2lnbmlmaWNhbnQoZXhwZWN0ZWQpXG5cbiAgICBpZiAobGVmdC5sZW5ndGggIT0gcmlnaHQubGVuZ3RoKSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IGNoaWxkcmVuXCIpXG4gICAgaWYgKCFsZWZ0Lmxlbmd0aCkge1xuICAgICAgY29uc3QgYWN0dWFsVGV4dCA9IGFjdHVhbC50eXBlID09IFwiY29tbWVudFwiICYmIC9zZW1hbnRpZm9sZDovdS50ZXN0KHRoaXMudGV4dChhY3R1YWwpKSA/IHRoaXMubWFya2VyKGFjdHVhbCkgOiB0aGlzLnRleHQoYWN0dWFsKVxuICAgICAgY29uc3QgZXhwZWN0ZWRUZXh0ID0gZXhwZWN0ZWQudHlwZSA9PSBcImNvbW1lbnRcIiAmJiAvc2VtYW50aWZvbGQ6L3UudGVzdChjYW5vbmljYWwudGV4dChleHBlY3RlZCkpID8gY2Fub25pY2FsLm1hcmtlcihleHBlY3RlZCkgOiBjYW5vbmljYWwudGV4dChleHBlY3RlZClcblxuICAgICAgaWYgKGFjdHVhbFRleHQgIT0gZXhwZWN0ZWRUZXh0KSB0aGlzLmZhaWwoYWN0dWFsLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IHRva2VuXCIpXG4gICAgfVxuICAgIGxlZnQuZm9yRWFjaCgoY2hpbGQsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBleHBlY3RlZENoaWxkID0gcmlnaHRbaW5kZXhdXG5cbiAgICAgIGlmICghZXhwZWN0ZWRDaGlsZCB8fCBhY3R1YWwuY2hpbGRyZW4uZmluZChlZGdlID0+IGVkZ2Uubm9kZSA9PT0gY2hpbGQpPy5maWVsZCAhPSBleHBlY3RlZC5jaGlsZHJlbi5maW5kKGVkZ2UgPT4gZWRnZS5ub2RlID09PSBleHBlY3RlZENoaWxkKT8uZmllbGQpIHtcbiAgICAgICAgdGhpcy5mYWlsKGNoaWxkLCBcIm1vZGlmaWVkIFppZyBzdXBwb3J0IGZpZWxkXCIpXG4gICAgICB9XG4gICAgICB0aGlzLmNvbXBhcmVUcmVlKGNoaWxkLCBleHBlY3RlZENoaWxkLCBjYW5vbmljYWwpXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhIHZhbGlkYXRlZCBleHByZXNzaW9uJ3Mgc2NhbGFyIHJlc3VsdC5cbiAgICogQHBhcmFtIHtFeHByZXNzaW9ufSBleHByZXNzaW9uIC0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTY2FsYXI+fSBiaW5kaW5ncyAtIFZpc2libGUgYmluZGluZyB0eXBlcy5cbiAgICogQHJldHVybnMge1NjYWxhcn0gU2NhbGFyIHJlc3VsdCBuYW1lLlxuICAgKi9cbiAgZXhwcmVzc2lvblR5cGUoZXhwcmVzc2lvbiwgYmluZGluZ3MpIHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiU3RyaW5nTGl0ZXJhbFwiKSByZXR1cm4gXCJzdHJpbmdcIlxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgPT0gXCJJbnRlZ2VyTGl0ZXJhbFwiKSByZXR1cm4gXCJpbnRlZ2VyXCJcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQm9vbGVhbkxpdGVyYWxcIikgcmV0dXJuIFwiYm9vbGVhblwiXG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIiB8fCBleHByZXNzaW9uLmtpbmQgPT0gXCJVbmFyeUV4cHJlc3Npb25cIikgcmV0dXJuIGV4cHJlc3Npb24udHlwZVxuICAgIGlmIChleHByZXNzaW9uLmtpbmQgIT0gXCJDYWxsRXhwcmVzc2lvblwiICYmIGV4cHJlc3Npb24ua2luZCAhPSBcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpIHRocm93IG5ldyBFcnJvcihcIlZhbGlkYXRlZCBaaWcgc291cmNlIGV4cG9zZWQgYSBjb2xsZWN0aW9uIGV4cHJlc3Npb24uXCIpXG4gICAgY29uc3QgdHlwZSA9IGV4cHJlc3Npb24ua2luZCA9PSBcIkNhbGxFeHByZXNzaW9uXCIgPyB0aGlzLmZ1bmN0aW9ucy5nZXQoZXhwcmVzc2lvbi5jYWxsZWUpIDogYmluZGluZ3MuZ2V0KGV4cHJlc3Npb24ubmFtZSlcblxuICAgIGlmICghdHlwZSkgdGhyb3cgbmV3IEVycm9yKFwiVmFsaWRhdGVkIFppZyBleHByZXNzaW9uIGxvc3QgaXRzIHNjYWxhciBiaW5kaW5nLlwiKVxuICAgIHJldHVybiB0eXBlXG4gIH1cblxuICAvKipcbiAgICogUmVxdWlyZXMgZWFjaCB0eXBlZCBvcGVyYXRpb24gdG8gcmV0YWluIHRoZSBvbmUgZXhhY3QgWmlnIG9wZXJhdG9yL2hlbHBlciBzcGVsbGluZyB0aGF0IGltcGxlbWVudHMgaXQuXG4gICAqIEBwYXJhbSB7RXhwcmVzc2lvbn0gZXhwcmVzc2lvbiAtIFJlc29sdmVkIHNjYWxhciBleHByZXNzaW9uLlxuICAgKi9cbiAgdmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKGV4cHJlc3Npb24pIHtcbiAgICBpZiAoZXhwcmVzc2lvbi5raW5kID09IFwiQ2FsbEV4cHJlc3Npb25cIikge1xuICAgICAgZXhwcmVzc2lvbi5hcmd1bWVudHMuZm9yRWFjaChhcmd1bWVudCA9PiB0aGlzLnZhbGlkYXRlT3BlcmF0aW9uRXhwcmVzc2lvbihhcmd1bWVudCkpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIlVuYXJ5RXhwcmVzc2lvblwiKSB7XG4gICAgICBjb25zdCBpZGVudGl0eSA9IHRoaXMub3BlcmF0aW9ucy5nZXQoZXhwcmVzc2lvbilcbiAgICAgIGNvbnN0IGV4cGVjdGVkID0gb3BlcmF0aW9uU3BlbGxpbmdzLmdldChleHByZXNzaW9uLm9wZXJhdGlvbilcblxuICAgICAgaWYgKCFpZGVudGl0eSkgdGhyb3cgbmV3IEVycm9yKFwiUmVzb2x2ZWQgWmlnIHVuYXJ5IG9wZXJhdGlvbiBsb3N0IGl0cyBwYXJzZXIgaWRlbnRpdHkuXCIpXG4gICAgICBpZiAoaWRlbnRpdHkuc3BlbGxpbmcgIT0gZXhwZWN0ZWQpIHRoaXMuZmFpbChpZGVudGl0eS5ub2RlLCBgZXhhY3QgJHtleHByZXNzaW9uLm9wZXJhdGlvbn0gWmlnIG9wZXJhdG9yL2hlbHBlciByZXF1aXJlZGApXG4gICAgICB0aGlzLnZhbGlkYXRlT3BlcmF0aW9uRXhwcmVzc2lvbihleHByZXNzaW9uLm9wZXJhbmQpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGV4cHJlc3Npb24ua2luZCA9PSBcIkJpbmFyeUV4cHJlc3Npb25cIikge1xuICAgICAgY29uc3QgaWRlbnRpdHkgPSB0aGlzLm9wZXJhdGlvbnMuZ2V0KGV4cHJlc3Npb24pXG4gICAgICBjb25zdCBleHBlY3RlZCA9IG9wZXJhdGlvblNwZWxsaW5ncy5nZXQoZXhwcmVzc2lvbi5vcGVyYXRpb24pXG5cbiAgICAgIGlmICghaWRlbnRpdHkpIHRocm93IG5ldyBFcnJvcihcIlJlc29sdmVkIFppZyBiaW5hcnkgb3BlcmF0aW9uIGxvc3QgaXRzIHBhcnNlciBpZGVudGl0eS5cIilcbiAgICAgIGlmIChpZGVudGl0eS5zcGVsbGluZyAhPSBleHBlY3RlZCkgdGhpcy5mYWlsKGlkZW50aXR5Lm5vZGUsIGBleGFjdCAke2V4cHJlc3Npb24ub3BlcmF0aW9ufSBaaWcgb3BlcmF0b3IvaGVscGVyIHJlcXVpcmVkYClcbiAgICAgIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKGV4cHJlc3Npb24ubGVmdClcbiAgICAgIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKGV4cHJlc3Npb24ucmlnaHQpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFZhbGlkYXRlcyBvcGVyYXRpb24gaWRlbnRpdHkgdGhyb3VnaG91dCBvbmUgbGV4aWNhbCBibG9jay5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBCbG9jayB3aG9zZSBleHByZXNzaW9ucyBtdXN0IHJldGFpbiBleGFjdCBaaWcgaWRlbnRpdHkuXG4gICAqL1xuICB2YWxpZGF0ZU9wZXJhdGlvbnMoYmxvY2spIHtcbiAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBibG9jay5zdGF0ZW1lbnRzKSB7XG4gICAgICBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJMb2NhbERlY2xhcmF0aW9uXCIpIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKHN0YXRlbWVudC5pbml0aWFsaXplcilcbiAgICAgIGVsc2UgaWYgKHN0YXRlbWVudC5raW5kID09IFwiQXNzaWdubWVudFN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiRXhwcmVzc2lvblN0YXRlbWVudFwiIHx8IHN0YXRlbWVudC5raW5kID09IFwiUHJpbnRTdGF0ZW1lbnRcIikge1xuICAgICAgICB0aGlzLnZhbGlkYXRlT3BlcmF0aW9uRXhwcmVzc2lvbihzdGF0ZW1lbnQuZXhwcmVzc2lvbilcbiAgICAgIH0gZWxzZSBpZiAoc3RhdGVtZW50LmtpbmQgPT0gXCJSZXR1cm5TdGF0ZW1lbnRcIikge1xuICAgICAgICBpZiAoc3RhdGVtZW50LmV4cHJlc3Npb24pIHRoaXMudmFsaWRhdGVPcGVyYXRpb25FeHByZXNzaW9uKHN0YXRlbWVudC5leHByZXNzaW9uKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZU9wZXJhdGlvbkV4cHJlc3Npb24oc3RhdGVtZW50LmNvbmRpdGlvbilcbiAgICAgICAgdGhpcy52YWxpZGF0ZU9wZXJhdGlvbnMoc3RhdGVtZW50LmNvbnNlcXVlbnQpXG4gICAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB0aGlzLnZhbGlkYXRlT3BlcmF0aW9ucyhzdGF0ZW1lbnQuYWx0ZXJuYXRlKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maXJtcyBlYWNoIGdlbmVyYXRlZCBvdXRwdXQgaGVscGVyIG1hdGNoZXMgaXRzIHNlbWFudGljIG9wZXJhbmQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2t9IGJsb2NrIC0gQmxvY2sgdG8gaW5zcGVjdC5cbiAgICogQHBhcmFtIHtNYXA8c3RyaW5nLCBTY2FsYXI+fSBpbmhlcml0ZWQgLSBWaXNpYmxlIGJpbmRpbmcgdHlwZXMuXG4gICAqL1xuICB2YWxpZGF0ZVByaW50cyhibG9jaywgaW5oZXJpdGVkKSB7XG4gICAgY29uc3QgYmluZGluZ3MgPSBuZXcgTWFwKGluaGVyaXRlZClcblxuICAgIGZvciAoY29uc3Qgc3RhdGVtZW50IG9mIGJsb2NrLnN0YXRlbWVudHMpIHtcbiAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICBiaW5kaW5ncy5zZXQoc3RhdGVtZW50Lm5hbWUsIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHN0YXRlbWVudC50eXBlKS5uYW1lKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIlByaW50U3RhdGVtZW50XCIpIHtcbiAgICAgICAgY29uc3QgcHJpbnQgPSB0aGlzLnByaW50cy5nZXQoc3RhdGVtZW50KVxuXG4gICAgICAgIGlmICghcHJpbnQgfHwgdGhpcy5leHByZXNzaW9uVHlwZShzdGF0ZW1lbnQuZXhwcmVzc2lvbiwgYmluZGluZ3MpICE9IHByaW50LnR5cGUpIHRoaXMuZmFpbChwcmludD8ubm9kZSA/PyAvKiogQHR5cGUge0NzdE5vZGV9ICovICh7fSksIFwicHJpbnQgaGVscGVyIHNjYWxhciBtaXNtYXRjaFwiKVxuICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgdGhpcy52YWxpZGF0ZVByaW50cyhzdGF0ZW1lbnQuY29uc2VxdWVudCwgYmluZGluZ3MpXG4gICAgICAgIGlmIChzdGF0ZW1lbnQuYWx0ZXJuYXRlKSB0aGlzLnZhbGlkYXRlUHJpbnRzKHN0YXRlbWVudC5hbHRlcm5hdGUsIGJpbmRpbmdzKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maXJtcyBhbGwgYW5kIG9ubHkgY29tcGlsZXItcmVxdWlyZWQgYmluZGluZyBzY2FmZm9sZHMgYXJlIHByZXNlbnQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbiB8IGltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkVudHJ5UG9pbnR9IG93bmVyIC0gRnVuY3Rpb24gb3IgZW50cnkgb3duZXIuXG4gICAqL1xuICB2YWxpZGF0ZVNjYWZmb2xkcyhvd25lcikge1xuICAgIGNvbnN0IHVzYWdlID0gY29sbGVjdFppZ0JpbmRpbmdVc2FnZShvd25lci5ib2R5KVxuICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBvd25lci5raW5kID09IFwiRnVuY3Rpb25EZWNsYXJhdGlvblwiID8gb3duZXIucGFyYW1ldGVycyA6IFtdXG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XG4gICAgICBjb25zdCBleHBlY3RlZCA9IHVzYWdlLnJlYWRzLmhhcyhwYXJhbWV0ZXIubmFtZSkgPyBcIm5vbmVcIiA6IFwidXNlXCJcblxuICAgICAgaWYgKHRoaXMuc2NhZmZvbGRzLmdldChwYXJhbWV0ZXIpICE9IGV4cGVjdGVkKSB1bnN1cHBvcnRlZFN5bnRheChcInppZ1wiLCBgaW5jb3JyZWN0IHVudXNlZC1wYXJhbWV0ZXIgc2NhZmZvbGQgZm9yICcke3BhcmFtZXRlci5uYW1lfSdgLCBwYXJhbWV0ZXIubG9jYXRpb24pXG4gICAgfVxuICAgIC8qKlxuICAgICAqIENoZWNrcyBsb2NhbCBzY2FmZm9sZHMgcmVjdXJzaXZlbHkuXG4gICAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5CbG9ja30gYmxvY2sgLSBCbG9jayB0byBpbnNwZWN0LlxuICAgICAqL1xuICAgIGNvbnN0IHZpc2l0ID0gKGJsb2NrKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHN0YXRlbWVudCBvZiBibG9jay5zdGF0ZW1lbnRzKSB7XG4gICAgICAgIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIkxvY2FsRGVjbGFyYXRpb25cIikge1xuICAgICAgICAgIGNvbnN0IGV4cGVjdGVkID0gc3RhdGVtZW50Lm11dGFibGUgJiYgIXVzYWdlLndyaXRlcy5oYXMoc3RhdGVtZW50Lm5hbWUpID8gXCJhZGRyZXNzXCIgOlxuICAgICAgICAgICAgIXN0YXRlbWVudC5tdXRhYmxlICYmICF1c2FnZS5yZWFkcy5oYXMoc3RhdGVtZW50Lm5hbWUpID8gXCJ1c2VcIiA6IFwibm9uZVwiXG5cbiAgICAgICAgICBpZiAodGhpcy5zY2FmZm9sZHMuZ2V0KHN0YXRlbWVudCkgIT0gZXhwZWN0ZWQpIHVuc3VwcG9ydGVkU3ludGF4KFwiemlnXCIsIGBpbmNvcnJlY3QgbG9jYWwgYmluZGluZyBzY2FmZm9sZCBmb3IgJyR7c3RhdGVtZW50Lm5hbWV9J2AsIHN0YXRlbWVudC5sb2NhdGlvbilcbiAgICAgICAgfSBlbHNlIGlmIChzdGF0ZW1lbnQua2luZCA9PSBcIklmU3RhdGVtZW50XCIpIHtcbiAgICAgICAgICB2aXNpdChzdGF0ZW1lbnQuY29uc2VxdWVudClcbiAgICAgICAgICBpZiAoc3RhdGVtZW50LmFsdGVybmF0ZSkgdmlzaXQoc3RhdGVtZW50LmFsdGVybmF0ZSlcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHZpc2l0KG93bmVyLmJvZHkpXG4gIH1cblxuICAvKipcbiAgICogQ29udmVydHMgYSBjb21wbGV0ZSBjYW5vbmljYWwgWmlnIHByb2plY3QgZW50cnkuXG4gICAqIEBwYXJhbSB7Q3N0Tm9kZX0gcm9vdCAtIFNvdXJjZS1maWxlIHJvb3QuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gVmFsaWRhdGVkIHNlbWFudGljIG1vZHVsZS5cbiAgICovXG4gIG1vZHVsZShyb290KSB7XG4gICAgdGhpcy52YWxpZGF0ZVRyZWUocm9vdClcbiAgICBpZiAocm9vdC50eXBlICE9IFwic291cmNlX2ZpbGVcIikgdGhpcy5mYWlsKHJvb3QsIFwiWmlnIHNvdXJjZSByb290IHJlcXVpcmVkXCIpXG4gICAgY29uc3QgY2Fub25pY2FsID0gbmV3IFppZ1JlYWRlcih0aGlzLmZpbGVuYW1lLCB6aWdSdW50aW1lKVxuICAgIGNvbnN0IHN1cHBvcnQgPSBjYW5vbmljYWwuc2lnbmlmaWNhbnQocGFyc2VaaWdDc3QoemlnUnVudGltZSkucm9vdClcbiAgICBjb25zdCBub2RlcyA9IHRoaXMuc2lnbmlmaWNhbnQocm9vdClcblxuICAgIGlmIChub2Rlcy5sZW5ndGggPCBzdXBwb3J0Lmxlbmd0aCArIDIpIHRoaXMuZmFpbChyb290LCBcImNvbXBsZXRlIFppZyBydW50aW1lLCBvcmRlcmVkIG1hcmtlciwgYW5kIG1haW4gc2hlbGwgcmVxdWlyZWRcIilcbiAgICBzdXBwb3J0LmZvckVhY2goKGV4cGVjdGVkLCBpbmRleCkgPT4gdGhpcy5jb21wYXJlVHJlZShub2Rlc1tpbmRleF0sIGV4cGVjdGVkLCBjYW5vbmljYWwpKVxuICAgIGNvbnN0IHByb2dyYW1NYXJrZXIgPSBub2Rlc1tzdXBwb3J0Lmxlbmd0aF1cblxuICAgIGlmIChwcm9ncmFtTWFya2VyLnR5cGUgIT0gXCJjb21tZW50XCIgfHwgdGhpcy5tYXJrZXIocHJvZ3JhbU1hcmtlcikgIT0gXCIvLyBzZW1hbnRpZm9sZDpwcm9ncmFtOnppZzp2MVwiKSB7XG4gICAgICB0aGlzLmZhaWwocHJvZ3JhbU1hcmtlciwgXCJleGFjdCBnZW5lcmF0ZWQgWmlnIG9yZGVyZWQtZXhwcmVzc2lvbiBtYXJrZXIgcmVxdWlyZWRcIilcbiAgICB9XG4gICAgdGhpcy5nZW5lcmF0ZWQgPSB0cnVlXG4gICAgY29uc3QgZGVmaW5pdGlvbnMgPSBub2Rlcy5zbGljZShzdXBwb3J0Lmxlbmd0aCArIDEpXG4gICAgLyoqIEB0eXBlIHtDc3ROb2RlIHwgdW5kZWZpbmVkfSAqL1xuICAgIGxldCBtYWluXG4gICAgLyoqIEB0eXBlIHtDc3ROb2RlW119ICovXG4gICAgY29uc3QgZnVuY3Rpb25zID0gW11cblxuICAgIGZvciAoY29uc3Qgbm9kZSBvZiBkZWZpbml0aW9ucykge1xuICAgICAgaWYgKG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2RlY2xhcmF0aW9uXCIpIHRoaXMuZmFpbChub2RlLCBcInRvcC1sZXZlbCBmcmVlIGZ1bmN0aW9ucyBvbmx5XCIpXG4gICAgICBjb25zdCBuYW1lID0gdGhpcy50ZXh0KHRoaXMuZmllbGQobm9kZSwgXCJuYW1lXCIpKVxuXG4gICAgICBpZiAobmFtZSA9PSBcIm1haW5cIikge1xuICAgICAgICBpZiAobWFpbikgdGhpcy5mYWlsKG5vZGUsIFwiZHVwbGljYXRlIG1haW5cIilcbiAgICAgICAgbWFpbiA9IG5vZGVcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChtYWluKSB0aGlzLmZhaWwobm9kZSwgXCJzZW1hbnRpYyBmdW5jdGlvbiBhZnRlciBtYWluXCIpXG4gICAgICAgIGZ1bmN0aW9ucy5wdXNoKG5vZGUpXG4gICAgICB9XG4gICAgfVxuICAgIGlmICghbWFpbikgdGhpcy5mYWlsKHJvb3QsIFwiY2Fub25pY2FsIHB1YiBmbiBtYWluKCkgdm9pZCByZXF1aXJlZFwiKVxuICAgIGNvbnN0IG1haW5QYXJ0cyA9IHRoaXMucGFydHMobWFpbilcbiAgICBjb25zdCBtYWluTmFtZSA9IHRoaXMuZmllbGQobWFpbiwgXCJuYW1lXCIpXG4gICAgY29uc3QgcGFyYW1ldGVycyA9IG1haW5QYXJ0cy5maW5kKGNoaWxkID0+IGNoaWxkLnR5cGUgPT0gXCJwYXJhbWV0ZXJzXCIpXG4gICAgY29uc3QgcmV0dXJuVHlwZSA9IHRoaXMuZmllbGQobWFpbiwgXCJ0eXBlXCIpXG4gICAgY29uc3QgYm9keSA9IHRoaXMuZmllbGQobWFpbiwgXCJib2R5XCIpXG5cbiAgICBpZiAoIXBhcmFtZXRlcnMpIHRoaXMuZmFpbChtYWluLCBcIm1haW4gcGFyYW1ldGVyc1wiKVxuICAgIHRoaXMuc2hhcGUobWFpbiwgW1wicHViXCIsIFwiZm5cIiwgbWFpbk5hbWUsIHBhcmFtZXRlcnMsIHJldHVyblR5cGUsIGJvZHldKVxuICAgIGlmICh0aGlzLnRleHQobWFpbk5hbWUpICE9IFwibWFpblwiKSB0aGlzLmZhaWwobWFpbk5hbWUsIFwibWFpbiBuYW1lXCIpXG4gICAgdGhpcy5zaGFwZShwYXJhbWV0ZXJzLCBbXCIoXCIsIFwiKVwiXSlcbiAgICB0aGlzLnR5cGUocmV0dXJuVHlwZSwgdHJ1ZSlcbiAgICBpZiAodGhpcy50ZXh0KHJldHVyblR5cGUpICE9IFwidm9pZFwiKSB0aGlzLmZhaWwocmV0dXJuVHlwZSwgXCJtYWluIHJldHVybiB0eXBlXCIpXG4gICAgY29uc3QgYm9keVBhcnRzID0gdGhpcy5wYXJ0cyhib2R5KVxuICAgIGNvbnN0IGRlZmVyTm9kZSA9IGJvZHlQYXJ0c1sxXVxuICAgIGNvbnN0IHNoZWxsU291cmNlID0gXCJwdWIgZm4gbWFpbigpIHZvaWQge1xcbiAgICBkZWZlciBzZW1hbnRpZm9sZF9hcmVuYS5kZWluaXQoKTtcXG59XFxuXCJcbiAgICBjb25zdCBzaGVsbFJlYWRlciA9IG5ldyBaaWdSZWFkZXIodGhpcy5maWxlbmFtZSwgc2hlbGxTb3VyY2UpXG4gICAgY29uc3Qgc2hlbGxNYWluID0gc2hlbGxSZWFkZXIucGFydHMocGFyc2VaaWdDc3Qoc2hlbGxTb3VyY2UpLnJvb3QpWzBdXG4gICAgY29uc3QgZXhwZWN0ZWREZWZlciA9IHNoZWxsUmVhZGVyLnBhcnRzKHNoZWxsUmVhZGVyLmZpZWxkKHNoZWxsTWFpbiwgXCJib2R5XCIpKVsxXVxuXG4gICAgaWYgKCFkZWZlck5vZGUpIHRoaXMuZmFpbChib2R5LCBcImFyZW5hIGxpZmV0aW1lIGRlZmVyIHJlcXVpcmVkXCIpXG4gICAgdGhpcy5jb21wYXJlVHJlZShkZWZlck5vZGUsIGV4cGVjdGVkRGVmZXIsIHNoZWxsUmVhZGVyKVxuICAgIGNvbnN0IG1vZHVsZSA9IHZhbGlkYXRlUGFyc2VkTW9kdWxlKHtraW5kOiBcIk1vZHVsZVwiLCBsb2NhdGlvbjogdGhpcy5sb2NhdGlvbihyb290KSwgZnVuY3Rpb25zOiBmdW5jdGlvbnMubWFwKG5vZGUgPT4gdGhpcy5mdW5jdGlvbihub2RlKSksXG4gICAgICBlbnRyeVBvaW50OiB7a2luZDogXCJFbnRyeVBvaW50XCIsIGxvY2F0aW9uOiB0aGlzLmxvY2F0aW9uKG1haW4pLCBib2R5OiB0aGlzLmJsb2NrKGJvZHksIDEpfX0sIFwiemlnXCIpXG5cbiAgICB0aGlzLmZ1bmN0aW9ucyA9IG5ldyBNYXAobW9kdWxlLmZ1bmN0aW9ucy5tYXAoZGVjbGFyYXRpb24gPT4gW2RlY2xhcmF0aW9uLm5hbWUsXG4gICAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlR5cGVSZWZlcmVuY2V9ICovIChkZWNsYXJhdGlvbi5yZXR1cm5UeXBlKS5uYW1lXSkpXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB0aGlzLnZhbGlkYXRlT3BlcmF0aW9ucyhkZWNsYXJhdGlvbi5ib2R5KVxuICAgIHRoaXMudmFsaWRhdGVPcGVyYXRpb25zKG1vZHVsZS5lbnRyeVBvaW50LmJvZHkpXG4gICAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBtb2R1bGUuZnVuY3Rpb25zKSB0aGlzLnZhbGlkYXRlUHJpbnRzKGRlY2xhcmF0aW9uLmJvZHksIG5ldyBNYXAoZGVjbGFyYXRpb24ucGFyYW1ldGVycy5tYXAocGFyYW1ldGVyID0+IFtwYXJhbWV0ZXIubmFtZSxcbiAgICAgIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gKi8gKHBhcmFtZXRlci50eXBlKS5uYW1lXSkpKVxuICAgIHRoaXMudmFsaWRhdGVQcmludHMobW9kdWxlLmVudHJ5UG9pbnQuYm9keSwgbmV3IE1hcCgpKVxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgbW9kdWxlLmZ1bmN0aW9ucykgdGhpcy52YWxpZGF0ZVNjYWZmb2xkcyhkZWNsYXJhdGlvbilcbiAgICB0aGlzLnZhbGlkYXRlU2NhZmZvbGRzKG1vZHVsZS5lbnRyeVBvaW50KVxuICAgIGNvbnN0IGNhbm9uaWNhbFNvdXJjZSA9IGdlbmVyYXRlWmlnUHJvamVjdCh7bW9kdWxlfSkuYXJ0aWZhY3RzWzFdPy5jb250ZW50XG5cbiAgICBpZiAodHlwZW9mIGNhbm9uaWNhbFNvdXJjZSAhPSBcInN0cmluZ1wiKSB0aHJvdyBuZXcgRXJyb3IoXCJaaWcgYmFja2VuZCByZXR1cm5lZCBhIG5vbnRleHQgZW50cnkgYXJ0aWZhY3QuXCIpXG4gICAgdGhpcy5jb21wYXJlVHJlZShyb290LCBwYXJzZVppZ0NzdChjYW5vbmljYWxTb3VyY2UpLnJvb3QsIG5ldyBaaWdSZWFkZXIodGhpcy5maWxlbmFtZSwgY2Fub25pY2FsU291cmNlKSlcbiAgICByZXR1cm4gbW9kdWxlXG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZXMgb25seSB0aGUgcXVhbGlmaWVkIGZyb3plbiBaaWcgQ1NUIGFuZCByZWplY3RzIHVuc3VwcG9ydGVkIGlucHV0IGJlZm9yZSBhZGFwdGF0aW9uLlxuICogQHBhcmFtIHt7ZmlsZW5hbWU6IHN0cmluZywgc291cmNlOiBzdHJpbmd9fSBpbnB1dCAtIEV4YWN0IHNvdXJjZSByZXF1ZXN0LlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlNlbWFudGljTW9kdWxlfSBaaWcgc2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VaaWcoe2ZpbGVuYW1lLCBzb3VyY2V9KSB7XG4gIGNvbnN0IGNvb3JkaW5hdGVzID0gY3JlYXRlQ29vcmRpbmF0ZUluZGV4KHNvdXJjZSlcbiAgY29uc3QgbG9jYXRpb24gPSB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgMCksIGVuZDogaW5kZXhlZFBvaW50QXQoY29vcmRpbmF0ZXMsIHNvdXJjZS5sZW5ndGgpfVxuXG4gIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHNvdXJjZSkpIHtcbiAgICBjb25zdCBvZmZzZXQgPSBzb3VyY2Uuc2VhcmNoKC9bXFx1RDgwMC1cXHVEQkZGXSg/IVtcXHVEQzAwLVxcdURGRkZdKXwoPzwhW1xcdUQ4MDAtXFx1REJGRl0pW1xcdURDMDAtXFx1REZGRl0vdSlcblxuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe2NvZGU6IFwiUEFSU0VfRVJST1JcIiwgbGFuZ3VhZ2U6IFwiemlnXCIsIG1lc3NhZ2U6IFwiWmlnIHNvdXJjZSBjb250YWlucyBhIGxvbmUgVVRGLTE2IHN1cnJvZ2F0ZS5cIixcbiAgICAgIGxvY2F0aW9uOiB7ZmlsZW5hbWUsIHN0YXJ0OiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0KSwgZW5kOiBpbmRleGVkUG9pbnRBdChjb29yZGluYXRlcywgb2Zmc2V0ICsgMSl9fSlcbiAgfVxuICBpZiAoc291cmNlLmxlbmd0aCA+IG1heGltdW1aaWdTb3VyY2VMZW5ndGgpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInppZ1wiLCBcInNvdXJjZSBleGNlZWRzIHRoZSAxMDAwMDAwIFVURi0xNiBpbnB1dCBsaW1pdFwiLCBsb2NhdGlvbilcbiAgbGV0IHNuYXBzaG90XG5cbiAgdHJ5IHtcbiAgICBzbmFwc2hvdCA9IHBhcnNlWmlnQ3N0KHNvdXJjZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICB0aHJvdyBuZXcgU2VtYW50aWZvbGREaWFnbm9zdGljKHtjb2RlOiBcIlBBUlNFX0VSUk9SXCIsIGxhbmd1YWdlOiBcInppZ1wiLCBsb2NhdGlvbixcbiAgICAgIGNhdXNlOiBlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiB1bmRlZmluZWQsIG1lc3NhZ2U6IFwiVGhlIHF1YWxpZmllZCBaaWcgcGFyc2VyIGNvdWxkIG5vdCBwcm9kdWNlIGEgY29tcGxldGUgQ1NULlwifSlcbiAgfVxuICBjb25zdCByZWFkZXIgPSBuZXcgWmlnUmVhZGVyKGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgdHJ5IHtcbiAgICByZXR1cm4gcmVhZGVyLm1vZHVsZShzbmFwc2hvdC5yb290KVxuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChyZWFkZXIuZ2VuZXJhdGVkICYmIGVycm9yIGluc3RhbmNlb2YgU2VtYW50aWZvbGREaWFnbm9zdGljICYmIGVycm9yLmxhbmd1YWdlID09IFwiemlnXCIgJiZcbiAgICAgIGVycm9yLmNvZGUgIT0gXCJQQVJTRV9FUlJPUlwiICYmIGVycm9yLmNvZGUgIT0gXCJVTlNVUFBPUlRFRF9TWU5UQVhcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwiemlnXCIsIGBpbnZhbGlkIGdlbmVyYXRlZCBvcmRlcmVkIHNjYWZmb2xkOiAke2Vycm9yLmNvZGV9YCwgZXJyb3IubG9jYXRpb24gPz8gbG9jYXRpb24pXG4gICAgfVxuICAgIHRocm93IGVycm9yXG4gIH1cbn1cbiJdfQ==
|