semantifold 0.1.1 → 0.3.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 +42 -10
- package/build/index.d.ts +32 -3
- package/build/index.d.ts.map +1 -1
- package/build/index.js +99 -4
- package/build/src/acceptance.d.ts +32 -0
- package/build/src/acceptance.d.ts.map +1 -0
- package/build/src/acceptance.js +358 -0
- package/build/src/array.d.ts +7 -0
- package/build/src/array.d.ts.map +1 -0
- package/build/src/array.js +18 -0
- package/build/src/artifact-path.d.ts +13 -0
- package/build/src/artifact-path.d.ts.map +1 -0
- package/build/src/artifact-path.js +30 -0
- package/build/src/artifacts.d.ts +7 -0
- package/build/src/artifacts.d.ts.map +1 -0
- package/build/src/artifacts.js +389 -0
- package/build/src/backends/c-runtime.d.ts +3 -0
- package/build/src/backends/c-runtime.d.ts.map +1 -0
- package/build/src/backends/c-runtime.js +151 -0
- package/build/src/backends/c-validation.d.ts +12 -0
- package/build/src/backends/c-validation.d.ts.map +1 -0
- package/build/src/backends/c-validation.js +85 -0
- package/build/src/backends/c.d.ts +31 -0
- package/build/src/backends/c.d.ts.map +1 -0
- package/build/src/backends/c.js +308 -0
- package/build/src/backends/cpp-runtime.d.ts +3 -0
- package/build/src/backends/cpp-runtime.d.ts.map +1 -0
- package/build/src/backends/cpp-runtime.js +99 -0
- package/build/src/backends/cpp-validation.d.ts +9 -0
- package/build/src/backends/cpp-validation.d.ts.map +1 -0
- package/build/src/backends/cpp-validation.js +74 -0
- package/build/src/backends/cpp.d.ts +16 -0
- package/build/src/backends/cpp.d.ts.map +1 -0
- package/build/src/backends/cpp.js +285 -0
- package/build/src/backends/csharp.d.ts +20 -0
- package/build/src/backends/csharp.d.ts.map +1 -0
- package/build/src/backends/csharp.js +259 -0
- package/build/src/backends/go.d.ts +20 -0
- package/build/src/backends/go.d.ts.map +1 -0
- package/build/src/backends/go.js +374 -0
- package/build/src/backends/identifiers.d.ts +12 -0
- package/build/src/backends/identifiers.d.ts.map +1 -1
- package/build/src/backends/identifiers.js +79 -2
- package/build/src/backends/index.d.ts.map +1 -1
- package/build/src/backends/index.js +27 -37
- package/build/src/backends/native-validation.d.ts +9 -0
- package/build/src/backends/native-validation.d.ts.map +1 -0
- package/build/src/backends/native-validation.js +59 -0
- package/build/src/backends/ordered-expressions.d.ts +74 -0
- package/build/src/backends/ordered-expressions.d.ts.map +1 -0
- package/build/src/backends/ordered-expressions.js +159 -0
- package/build/src/backends/python.d.ts +8 -0
- package/build/src/backends/python.d.ts.map +1 -0
- package/build/src/backends/python.js +162 -0
- package/build/src/backends/scalars.d.ts.map +1 -1
- package/build/src/backends/scalars.js +8 -2
- package/build/src/backends/shared.d.ts.map +1 -1
- package/build/src/backends/shared.js +67 -19
- package/build/src/binary-mapping.d.ts +32 -0
- package/build/src/binary-mapping.d.ts.map +1 -0
- package/build/src/binary-mapping.js +285 -0
- package/build/src/diagnostic.d.ts +36 -4
- package/build/src/diagnostic.d.ts.map +1 -1
- package/build/src/diagnostic.js +42 -3
- package/build/src/frontends/c-parser.d.ts +20 -0
- package/build/src/frontends/c-parser.d.ts.map +1 -0
- package/build/src/frontends/c-parser.js +14 -0
- package/build/src/frontends/c.d.ts +220 -0
- package/build/src/frontends/c.d.ts.map +1 -0
- package/build/src/frontends/c.js +750 -0
- package/build/src/frontends/cpp-parser.d.ts +11 -0
- package/build/src/frontends/cpp-parser.d.ts.map +1 -0
- package/build/src/frontends/cpp-parser.js +15 -0
- package/build/src/frontends/cpp.d.ts +227 -0
- package/build/src/frontends/cpp.d.ts.map +1 -0
- package/build/src/frontends/cpp.js +784 -0
- package/build/src/frontends/csharp.d.ts +14 -0
- package/build/src/frontends/csharp.d.ts.map +1 -0
- package/build/src/frontends/csharp.js +708 -0
- package/build/src/frontends/go.d.ts +15 -0
- package/build/src/frontends/go.d.ts.map +1 -0
- package/build/src/frontends/go.js +712 -0
- package/build/src/frontends/index.d.ts.map +1 -1
- package/build/src/frontends/index.js +5 -23
- package/build/src/frontends/python.d.ts +14 -0
- package/build/src/frontends/python.d.ts.map +1 -0
- package/build/src/frontends/python.js +615 -0
- package/build/src/frontends/scalars.d.ts.map +1 -1
- package/build/src/frontends/scalars.js +21 -1
- package/build/src/language-registry.d.ts +113 -0
- package/build/src/language-registry.d.ts.map +1 -0
- package/build/src/language-registry.js +421 -0
- package/build/src/mapping.js +3 -2
- package/build/src/semantic/location.d.ts +7 -0
- package/build/src/semantic/location.d.ts.map +1 -1
- package/build/src/semantic/location.js +10 -1
- package/build/src/semantic/provenance.js +3 -3
- package/build/src/semantic/types.d.ts +399 -2
- package/build/src/semantic/types.d.ts.map +1 -1
- package/build/src/semantic/types.js +110 -2
- package/build/src/subprocess.d.ts +38 -0
- package/build/src/subprocess.d.ts.map +1 -0
- package/build/src/subprocess.js +233 -0
- package/build/src/timeout.d.ts +8 -0
- package/build/src/timeout.d.ts.map +1 -0
- package/build/src/timeout.js +11 -0
- package/build/src/toolchains.d.ts +107 -0
- package/build/src/toolchains.d.ts.map +1 -0
- package/build/src/toolchains.js +417 -0
- package/docs/architecture.md +23 -5
- package/docs/c.md +60 -0
- package/docs/cpp.md +61 -0
- package/docs/goals.md +4 -2
- package/docs/language-support.md +46 -6
- package/docs/parser-qualification.md +219 -0
- package/docs/plans/2026-09-05-standard-library-portability.md +46 -0
- package/docs/source-maps.md +38 -5
- package/docs/standard-library-portability.md +190 -0
- package/docs/testing.md +131 -3
- package/index.js +109 -4
- package/node_modules/node-addon-api/LICENSE.md +9 -0
- package/node_modules/node-addon-api/README.md +95 -0
- package/node_modules/node-addon-api/common.gypi +21 -0
- package/node_modules/node-addon-api/except.gypi +25 -0
- package/node_modules/node-addon-api/index.js +14 -0
- package/node_modules/node-addon-api/napi-inl.deprecated.h +186 -0
- package/node_modules/node-addon-api/napi-inl.h +7250 -0
- package/node_modules/node-addon-api/napi.h +3463 -0
- package/node_modules/node-addon-api/node_addon_api.gyp +42 -0
- package/node_modules/node-addon-api/node_api.gyp +9 -0
- package/node_modules/node-addon-api/noexcept.gypi +26 -0
- package/node_modules/node-addon-api/nothing.c +0 -0
- package/node_modules/node-addon-api/package-support.json +21 -0
- package/node_modules/node-addon-api/package.json +481 -0
- package/node_modules/node-addon-api/tools/README.md +73 -0
- package/node_modules/node-addon-api/tools/check-napi.js +99 -0
- package/node_modules/node-addon-api/tools/clang-format.js +71 -0
- package/node_modules/node-addon-api/tools/conversion.js +301 -0
- package/node_modules/node-gyp-build/LICENSE +21 -0
- package/node_modules/node-gyp-build/README.md +58 -0
- package/node_modules/node-gyp-build/SECURITY.md +5 -0
- package/node_modules/node-gyp-build/bin.js +84 -0
- package/node_modules/node-gyp-build/build-test.js +19 -0
- package/node_modules/node-gyp-build/index.js +6 -0
- package/node_modules/node-gyp-build/node-gyp-build.js +207 -0
- package/node_modules/node-gyp-build/optional.js +7 -0
- package/node_modules/node-gyp-build/package.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/LICENSE +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/README.md +7 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/README.md +90 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/binding.gyp +79 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/index.js +895 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/package.json +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.cc +106 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.cc +1056 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.cc +298 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.cc +383 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/query.h +39 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.cc +307 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/tree-sitter.d.ts +211 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +501 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +221 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +299 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +419 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +49 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +14 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +774 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2151 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +230 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +62 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4134 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +899 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1060 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +382 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +165 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +714 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +50 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +23 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +109 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1294 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1823 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/README.md +18 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/binding.gyp +29 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/grammar.js +1470 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/package.json +60 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/darwin-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/linux-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-arm64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/prebuilds/win32-x64/tree-sitter-c.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/highlights.scm +81 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/queries/tags.scm +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/grammar.json +9735 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/node-types.json +4614 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/parser.c +119615 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter-c.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-c/tree-sitter.json +43 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/LICENSE +21 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/README.md +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/binding.gyp +30 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding.cc +20 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/binding_test.js +9 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.d.ts +28 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/bindings/node/index.js +11 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/grammar.js +1436 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/package.json +61 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/darwin-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/linux-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-arm64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/prebuilds/win32-x64/tree-sitter-cpp.node +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/highlights.scm +70 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/injections.scm +3 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/queries/tags.scm +15 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/grammar.json +17084 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/node-types.json +7997 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/parser.c +530368 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/scanner.c +148 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/alloc.h +54 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/array.h +290 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/src/tree_sitter/parser.h +266 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter-cpp.wasm +0 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/node_modules/tree-sitter-cpp/tree-sitter.json +55 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/package.json +22 -0
- package/node_modules/semantifold-tree-sitter-legacy-internal/src/c.js +152 -0
- package/node_modules/tree-sitter/LICENSE +21 -0
- package/node_modules/tree-sitter/README.md +128 -0
- package/node_modules/tree-sitter/binding.gyp +88 -0
- package/node_modules/tree-sitter/index.js +950 -0
- package/node_modules/tree-sitter/package.json +76 -0
- package/node_modules/tree-sitter/prebuilds/darwin-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/darwin-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/linux-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-arm64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/prebuilds/win32-x64/tree-sitter.node +0 -0
- package/node_modules/tree-sitter/src/addon_data.h +47 -0
- package/node_modules/tree-sitter/src/binding.cc +35 -0
- package/node_modules/tree-sitter/src/conversions.cc +140 -0
- package/node_modules/tree-sitter/src/conversions.h +22 -0
- package/node_modules/tree-sitter/src/language.cc +105 -0
- package/node_modules/tree-sitter/src/language.h +17 -0
- package/node_modules/tree-sitter/src/logger.cc +70 -0
- package/node_modules/tree-sitter/src/logger.h +19 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.cc +122 -0
- package/node_modules/tree-sitter/src/lookaheaditerator.h +33 -0
- package/node_modules/tree-sitter/src/node.cc +1088 -0
- package/node_modules/tree-sitter/src/node.h +30 -0
- package/node_modules/tree-sitter/src/parser.cc +332 -0
- package/node_modules/tree-sitter/src/parser.h +35 -0
- package/node_modules/tree-sitter/src/query.cc +425 -0
- package/node_modules/tree-sitter/src/query.h +40 -0
- package/node_modules/tree-sitter/src/tree.cc +316 -0
- package/node_modules/tree-sitter/src/tree.h +45 -0
- package/node_modules/tree-sitter/src/tree_cursor.cc +213 -0
- package/node_modules/tree-sitter/src/tree_cursor.h +52 -0
- package/node_modules/tree-sitter/tree-sitter.d.ts +1083 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/include/tree_sitter/api.h +1478 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.c +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/alloc.h +41 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/array.h +291 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/atomic.h +68 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/clock.h +146 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/error_costs.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.c +523 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/get_changed_ranges.h +36 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/host.h +21 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.c +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/language.h +293 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/length.h +52 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.c +483 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lexer.h +54 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/lib.c +12 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/node.c +875 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.c +2297 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/parser.h +286 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/point.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/portable/endian.h +241 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/query.c +4347 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reduce_action.h +34 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/reusable_node.h +95 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.c +912 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/stack.h +133 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.c +1034 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/subtree.h +399 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.c +170 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree.h +31 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.c +716 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/tree_cursor.h +48 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/ts_assert.h +11 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ICU_SHA +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/LICENSE +414 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/README.md +29 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/ptypes.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/umachine.h +448 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/urename.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf.h +1 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf16.h +733 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode/utf8.h +881 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/unicode.h +75 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib-symbols.txt +24 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/stdlib.c +137 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm/wasm-stdlib.h +1314 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.c +1937 -0
- package/node_modules/tree-sitter/vendor/tree-sitter/lib/src/wasm_store.h +31 -0
- package/package.json +24 -6
- package/src/acceptance.js +380 -0
- package/src/array.js +19 -0
- package/src/artifact-path.js +34 -0
- package/src/artifacts.js +420 -0
- package/src/backends/c-runtime.js +151 -0
- package/src/backends/c-validation.js +83 -0
- package/src/backends/c.js +308 -0
- package/src/backends/cpp-runtime.js +99 -0
- package/src/backends/cpp-validation.js +70 -0
- package/src/backends/cpp.js +285 -0
- package/src/backends/csharp.js +270 -0
- package/src/backends/go.js +383 -0
- package/src/backends/identifiers.js +80 -1
- package/src/backends/index.js +23 -32
- package/src/backends/native-validation.js +64 -0
- package/src/backends/ordered-expressions.js +161 -0
- package/src/backends/python.js +175 -0
- package/src/backends/scalars.js +8 -1
- package/src/backends/shared.js +64 -17
- package/src/binary-mapping.js +305 -0
- package/src/diagnostic.js +34 -2
- package/src/frontends/c-parser.js +17 -0
- package/src/frontends/c.js +780 -0
- package/src/frontends/cpp-parser.js +18 -0
- package/src/frontends/cpp.js +816 -0
- package/src/frontends/csharp.js +759 -0
- package/src/frontends/go.js +770 -0
- package/src/frontends/index.js +5 -20
- package/src/frontends/python.js +689 -0
- package/src/frontends/scalars.js +20 -0
- package/src/language-registry.js +454 -0
- package/src/mapping.js +2 -1
- package/src/semantic/location.js +10 -0
- package/src/semantic/provenance.js +2 -2
- package/src/semantic/types.js +124 -1
- package/src/subprocess.js +232 -0
- package/src/timeout.js +12 -0
- package/src/toolchains.js +448 -0
- package/tsconfig.json +1 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
import Parser from "tree-sitter";
|
|
3
|
+
import PythonLanguage from "tree-sitter-python";
|
|
4
|
+
import { missingType, parseFailure, SemantifoldDiagnostic, unsupportedSyntax } from "../diagnostic.js";
|
|
5
|
+
import { locationFromOffsets, moduleLocation, utf8ByteOffsetToUtf16Offset } from "../semantic/location.js";
|
|
6
|
+
import { withAdaptedOperation } from "../semantic/operators.js";
|
|
7
|
+
import { withParserRanges } from "../semantic/provenance.js";
|
|
8
|
+
import { hasOnlyUnicodeScalars } from "../semantic/scalars.js";
|
|
9
|
+
import { requireSourceScalarType } from "./scalars.js";
|
|
10
|
+
const parser = new Parser();
|
|
11
|
+
parser.setLanguage(/** @type {import("tree-sitter").Language} */ ( /** @type {unknown} */(PythonLanguage)));
|
|
12
|
+
const immutableMarker = "# @semantifold-immutable";
|
|
13
|
+
const pythonReservedIdentifiers = new Set([
|
|
14
|
+
"False", "None", "True", "and", "as", "assert", "async", "await", "break", "case", "class", "continue",
|
|
15
|
+
"def", "del", "elif", "else", "except", "exec", "finally", "for", "from", "global", "if", "import", "in",
|
|
16
|
+
"is", "lambda", "match", "nonlocal", "not", "or", "pass", "print", "raise", "return", "try", "type",
|
|
17
|
+
"while", "with", "yield", "_", "__debug__", "int", "bool", "str"
|
|
18
|
+
]);
|
|
19
|
+
const binaryOperations = new Map([
|
|
20
|
+
["+", "Add"],
|
|
21
|
+
["-", "Subtract"],
|
|
22
|
+
["*", "Multiply"]
|
|
23
|
+
]);
|
|
24
|
+
const comparisonOperations = new Map([
|
|
25
|
+
["==", "Equal"],
|
|
26
|
+
["!=", "NotEqual"],
|
|
27
|
+
["<", "LessThan"],
|
|
28
|
+
["<=", "LessThanOrEqual"],
|
|
29
|
+
[">", "GreaterThan"],
|
|
30
|
+
[">=", "GreaterThanOrEqual"]
|
|
31
|
+
]);
|
|
32
|
+
/** @typedef {{comments: import("tree-sitter").SyntaxNode[], usedImmutableMarkers: Set<import("tree-sitter").SyntaxNode>}} PythonContext */
|
|
33
|
+
/**
|
|
34
|
+
* Routes the binding's UTF-16 index through the shared UTF-8 byte converter.
|
|
35
|
+
* node-tree-sitter parses JavaScript strings as UTF-16LE and exposes code-unit
|
|
36
|
+
* indexes even though the grammar's native coordinate contract is byte-based.
|
|
37
|
+
* @param {string} source - Complete source.
|
|
38
|
+
* @param {number} index - Binding UTF-16 index.
|
|
39
|
+
* @returns {number} Verified UTF-16 offset.
|
|
40
|
+
*/
|
|
41
|
+
function bindingIndexToUtf16Offset(source, index) {
|
|
42
|
+
if (!Number.isInteger(index) || index < 0 || index > source.length ||
|
|
43
|
+
index > 0 && index < source.length && /[\uD800-\uDBFF]/u.test(source[index - 1]) && /[\uDC00-\uDFFF]/u.test(source[index])) {
|
|
44
|
+
throw new RangeError(`Invalid Tree-sitter source index: ${index}`);
|
|
45
|
+
}
|
|
46
|
+
const byteOffset = new TextEncoder().encode(source.slice(0, index)).length;
|
|
47
|
+
return utf8ByteOffsetToUtf16Offset(source, byteOffset);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Finds the first unpaired UTF-16 surrogate.
|
|
51
|
+
* @param {string} source - Complete source.
|
|
52
|
+
* @returns {number} Invalid offset, or -1.
|
|
53
|
+
*/
|
|
54
|
+
function firstLoneSurrogateOffset(source) {
|
|
55
|
+
for (let index = 0; index < source.length; index += 1) {
|
|
56
|
+
const unit = source.charCodeAt(index);
|
|
57
|
+
if (unit >= 0xD800 && unit <= 0xDBFF) {
|
|
58
|
+
const next = source.charCodeAt(index + 1);
|
|
59
|
+
if (next >= 0xDC00 && next <= 0xDFFF)
|
|
60
|
+
index += 1;
|
|
61
|
+
else
|
|
62
|
+
return index;
|
|
63
|
+
}
|
|
64
|
+
else if (unit >= 0xDC00 && unit <= 0xDFFF)
|
|
65
|
+
return index;
|
|
66
|
+
}
|
|
67
|
+
return -1;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Converts a Tree-sitter byte range into Semantifold's UTF-16 coordinates.
|
|
71
|
+
* @param {import("tree-sitter").SyntaxNode} node - Parser node.
|
|
72
|
+
* @param {string} filename - Source filename.
|
|
73
|
+
* @param {string} source - Complete source.
|
|
74
|
+
* @returns {import("../semantic/types.js").SourceLocation} Exact location.
|
|
75
|
+
*/
|
|
76
|
+
function nodeLocation(node, filename, source) {
|
|
77
|
+
return locationFromOffsets(filename, source, bindingIndexToUtf16Offset(source, node.startIndex), bindingIndexToUtf16Offset(source, node.endIndex));
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Requires one parser field.
|
|
81
|
+
* @param {import("tree-sitter").SyntaxNode} node - Field owner.
|
|
82
|
+
* @param {string} field - Grammar field name.
|
|
83
|
+
* @param {string} filename - Source filename.
|
|
84
|
+
* @param {string} source - Complete source.
|
|
85
|
+
* @returns {import("tree-sitter").SyntaxNode} Field node.
|
|
86
|
+
*/
|
|
87
|
+
function requiredField(node, field, filename, source) {
|
|
88
|
+
const child = node.childForFieldName(field);
|
|
89
|
+
if (!child)
|
|
90
|
+
return unsupportedSyntax("python", `${node.type} without ${field}`, nodeLocation(node, filename, source));
|
|
91
|
+
return child;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Validates every named and anonymous parser child and rejects recovery.
|
|
95
|
+
* @param {import("tree-sitter").SyntaxNode} node - Current parser node.
|
|
96
|
+
* @param {string} filename - Source filename.
|
|
97
|
+
* @param {string} source - Complete source.
|
|
98
|
+
* @returns {void}
|
|
99
|
+
*/
|
|
100
|
+
function validateParserTree(node, filename, source) {
|
|
101
|
+
if (node.isError || node.isMissing) {
|
|
102
|
+
throw new SemantifoldDiagnostic({
|
|
103
|
+
code: "PARSE_ERROR",
|
|
104
|
+
language: "python",
|
|
105
|
+
location: nodeLocation(node, filename, source),
|
|
106
|
+
message: `Tree-sitter exposed ${node.isMissing ? "a missing" : "an error"} recovery node '${node.type}'.`
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
for (let index = 0; index < node.childCount; index += 1) {
|
|
110
|
+
const child = node.child(index);
|
|
111
|
+
if (!child)
|
|
112
|
+
throw new Error(`Tree-sitter omitted child ${index} of ${node.type}.`);
|
|
113
|
+
validateParserTree(child, filename, source);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Rejects Python identifiers that cannot safely participate in the exact profile.
|
|
118
|
+
* @param {import("tree-sitter").SyntaxNode} node - Identifier node.
|
|
119
|
+
* @param {string} role - Diagnostic role.
|
|
120
|
+
* @param {string} filename - Source filename.
|
|
121
|
+
* @param {string} source - Complete source.
|
|
122
|
+
* @returns {string} Accepted name.
|
|
123
|
+
*/
|
|
124
|
+
function identifier(node, role, filename, source) {
|
|
125
|
+
const name = node.text;
|
|
126
|
+
if (node.type != "identifier" || pythonReservedIdentifiers.has(name) || name.normalize("NFKC") != name) {
|
|
127
|
+
return unsupportedSyntax("python", `${role} identifier '${name}'`, nodeLocation(node, filename, source));
|
|
128
|
+
}
|
|
129
|
+
return name;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Converts one exact int/bool/str annotation.
|
|
133
|
+
* @param {import("tree-sitter").SyntaxNode | null} node - Type node, if present.
|
|
134
|
+
* @param {string} subject - Typed subject.
|
|
135
|
+
* @param {import("../semantic/types.js").SourceLocation} ownerLocation - Owning declaration.
|
|
136
|
+
* @param {string} filename - Source filename.
|
|
137
|
+
* @param {string} source - Complete source.
|
|
138
|
+
* @returns {import("../semantic/types.js").TypeReference} Semantic type.
|
|
139
|
+
*/
|
|
140
|
+
function convertType(node, subject, ownerLocation, filename, source) {
|
|
141
|
+
if (!node)
|
|
142
|
+
return missingType("python", subject, ownerLocation);
|
|
143
|
+
const typeLocation = nodeLocation(node, filename, source);
|
|
144
|
+
const children = node.namedChildren.filter((child) => child.type != "comment");
|
|
145
|
+
if (node.type != "type" || children.length != 1 || children[0].type != "identifier" ||
|
|
146
|
+
!["int", "bool", "str"].includes(children[0].text) || node.text != children[0].text) {
|
|
147
|
+
return unsupportedSyntax("python", "unsupported scalar annotation", typeLocation);
|
|
148
|
+
}
|
|
149
|
+
return requireSourceScalarType("python", children[0].text, subject, ownerLocation, typeLocation);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Finds exactly one anonymous operator token directly owned by a parser node.
|
|
153
|
+
* @param {import("tree-sitter").SyntaxNode} node - Operation node.
|
|
154
|
+
* @param {Set<string>} spellings - Accepted spellings.
|
|
155
|
+
* @param {string} filename - Source filename.
|
|
156
|
+
* @param {string} source - Complete source.
|
|
157
|
+
* @returns {import("tree-sitter").SyntaxNode} Operator token.
|
|
158
|
+
*/
|
|
159
|
+
function operatorToken(node, spellings, filename, source) {
|
|
160
|
+
const tokens = node.children.filter((child) => !child.isNamed && spellings.has(child.type));
|
|
161
|
+
if (tokens.length != 1)
|
|
162
|
+
return unsupportedSyntax("python", `${node.type} operator`, nodeLocation(node, filename, source));
|
|
163
|
+
return tokens[0];
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Converts one supported Python expression.
|
|
167
|
+
* @param {import("tree-sitter").SyntaxNode} node - Expression node.
|
|
168
|
+
* @param {string} filename - Source filename.
|
|
169
|
+
* @param {string} source - Complete source.
|
|
170
|
+
* @returns {import("../semantic/types.js").Expression} Semantic expression.
|
|
171
|
+
*/
|
|
172
|
+
function convertExpression(node, filename, source) {
|
|
173
|
+
const location = nodeLocation(node, filename, source);
|
|
174
|
+
if (node.type == "parenthesized_expression") {
|
|
175
|
+
const expressions = node.namedChildren.filter((child) => child.type != "comment");
|
|
176
|
+
if (expressions.length != 1)
|
|
177
|
+
return unsupportedSyntax("python", node.type, location);
|
|
178
|
+
return convertExpression(expressions[0], filename, source);
|
|
179
|
+
}
|
|
180
|
+
if (node.type == "identifier") {
|
|
181
|
+
const name = identifier(node, "reference", filename, source);
|
|
182
|
+
return withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location, name }, { name: location });
|
|
183
|
+
}
|
|
184
|
+
if (node.type == "integer") {
|
|
185
|
+
let value;
|
|
186
|
+
try {
|
|
187
|
+
value = Number(BigInt(node.text.replaceAll("_", "")));
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return unsupportedSyntax("python", "integer literal", location);
|
|
191
|
+
}
|
|
192
|
+
if (!Number.isSafeInteger(value))
|
|
193
|
+
return unsupportedSyntax("python", "non-safe integer literal", location);
|
|
194
|
+
return withParserRanges({ kind: /** @type {const} */ ("IntegerLiteral"), location, value }, { literal: location });
|
|
195
|
+
}
|
|
196
|
+
if (node.type == "true" || node.type == "false") {
|
|
197
|
+
return withParserRanges({ kind: /** @type {const} */ ("BooleanLiteral"), location, value: node.type == "true" }, { literal: location });
|
|
198
|
+
}
|
|
199
|
+
if (node.type == "string") {
|
|
200
|
+
return withParserRanges({ kind: /** @type {const} */ ("StringLiteral"), location, value: decodeString(node, filename, source) }, {
|
|
201
|
+
literal: location
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
if (node.type == "concatenated_string")
|
|
205
|
+
return unsupportedSyntax("python", "implicit string concatenation", location);
|
|
206
|
+
if (node.type == "unary_operator") {
|
|
207
|
+
const operandNode = requiredField(node, "argument", filename, source);
|
|
208
|
+
const operator = operatorToken(node, new Set(["-"]), filename, source);
|
|
209
|
+
const semantic = withAdaptedOperation(withParserRanges({
|
|
210
|
+
kind: "UnaryExpression",
|
|
211
|
+
location,
|
|
212
|
+
operand: convertExpression(operandNode, filename, source)
|
|
213
|
+
}, { operator: nodeLocation(operator, filename, source) }), "Negate");
|
|
214
|
+
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(semantic));
|
|
215
|
+
}
|
|
216
|
+
if (node.type == "not_operator") {
|
|
217
|
+
const operandNode = requiredField(node, "argument", filename, source);
|
|
218
|
+
const operator = operatorToken(node, new Set(["not"]), filename, source);
|
|
219
|
+
const semantic = withAdaptedOperation(withParserRanges({
|
|
220
|
+
kind: "UnaryExpression",
|
|
221
|
+
location,
|
|
222
|
+
operand: convertExpression(operandNode, filename, source)
|
|
223
|
+
}, { operator: nodeLocation(operator, filename, source) }), "Not");
|
|
224
|
+
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(semantic));
|
|
225
|
+
}
|
|
226
|
+
if (node.type == "binary_operator" || node.type == "comparison_operator" || node.type == "boolean_operator") {
|
|
227
|
+
const expressionChildren = node.namedChildren.filter((child) => child.type != "comment");
|
|
228
|
+
const leftNode = node.childForFieldName("left") ?? expressionChildren[0];
|
|
229
|
+
const rightNode = node.childForFieldName("right") ?? expressionChildren[1];
|
|
230
|
+
if (!leftNode || !rightNode)
|
|
231
|
+
return unsupportedSyntax("python", node.type, location);
|
|
232
|
+
const operations = node.type == "binary_operator" ? binaryOperations : node.type == "comparison_operator"
|
|
233
|
+
? comparisonOperations : new Map([["and", "And"], ["or", "Or"]]);
|
|
234
|
+
const operator = operatorToken(node, new Set(operations.keys()), filename, source);
|
|
235
|
+
const adapted = operations.get(operator.type);
|
|
236
|
+
if (!adapted || expressionChildren.length != 2) {
|
|
237
|
+
return unsupportedSyntax("python", node.type, location);
|
|
238
|
+
}
|
|
239
|
+
const semantic = withAdaptedOperation(withParserRanges({
|
|
240
|
+
kind: "BinaryExpression",
|
|
241
|
+
left: convertExpression(leftNode, filename, source),
|
|
242
|
+
location,
|
|
243
|
+
right: convertExpression(rightNode, filename, source)
|
|
244
|
+
}, { operator: nodeLocation(operator, filename, source) }), /** @type {import("../semantic/operators.js").AdaptedOperation} */ (adapted));
|
|
245
|
+
return /** @type {import("../semantic/types.js").Expression} */ ( /** @type {unknown} */(semantic));
|
|
246
|
+
}
|
|
247
|
+
if (node.type == "call") {
|
|
248
|
+
const calleeNode = requiredField(node, "function", filename, source);
|
|
249
|
+
const argumentsNode = requiredField(node, "arguments", filename, source);
|
|
250
|
+
if (calleeNode.type != "identifier" || argumentsNode.type != "argument_list") {
|
|
251
|
+
return unsupportedSyntax("python", "dynamic call", location);
|
|
252
|
+
}
|
|
253
|
+
const callee = identifier(calleeNode, "callee", filename, source);
|
|
254
|
+
const arguments_ = argumentsNode.namedChildren.filter((child) => child.type != "comment")
|
|
255
|
+
.map((argument) => convertExpression(argument, filename, source));
|
|
256
|
+
return withParserRanges({ arguments: arguments_, callee, kind: /** @type {const} */ ("CallExpression"), location }, {
|
|
257
|
+
callee: nodeLocation(calleeNode, filename, source)
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
return unsupportedSyntax("python", node.type, location);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Decodes one non-prefixed, non-triple Python string without evaluating source.
|
|
264
|
+
* @param {import("tree-sitter").SyntaxNode} node - String node.
|
|
265
|
+
* @param {string} filename - Source filename.
|
|
266
|
+
* @param {string} source - Complete source.
|
|
267
|
+
* @returns {string} Unicode scalar string.
|
|
268
|
+
*/
|
|
269
|
+
function decodeString(node, filename, source) {
|
|
270
|
+
const location = nodeLocation(node, filename, source);
|
|
271
|
+
const text = node.text;
|
|
272
|
+
const quote = text[0];
|
|
273
|
+
if ((quote != "\"" && quote != "'") || text.at(-1) != quote || text.startsWith(`${quote}${quote}${quote}`)) {
|
|
274
|
+
return unsupportedSyntax("python", "prefixed or triple-quoted string", location);
|
|
275
|
+
}
|
|
276
|
+
let decoded = "";
|
|
277
|
+
for (let index = 1; index < text.length - 1; index += 1) {
|
|
278
|
+
const character = text[index];
|
|
279
|
+
if (character != "\\") {
|
|
280
|
+
decoded += character;
|
|
281
|
+
continue;
|
|
282
|
+
}
|
|
283
|
+
const escape = text[++index];
|
|
284
|
+
if (escape === undefined)
|
|
285
|
+
return unsupportedSyntax("python", "invalid string escape", location);
|
|
286
|
+
const simple = new Map([
|
|
287
|
+
["\\", "\\"], ["'", "'"], ["\"", "\""], ["a", "\u0007"], ["b", "\b"], ["f", "\f"], ["n", "\n"],
|
|
288
|
+
["r", "\r"], ["t", "\t"], ["v", "\v"]
|
|
289
|
+
]);
|
|
290
|
+
if (simple.has(escape)) {
|
|
291
|
+
decoded += simple.get(escape);
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
if (/[0-7]/u.test(escape)) {
|
|
295
|
+
let digits = escape;
|
|
296
|
+
while (digits.length < 3 && /[0-7]/u.test(text[index + 1] ?? ""))
|
|
297
|
+
digits += text[++index];
|
|
298
|
+
decoded += String.fromCodePoint(Number.parseInt(digits, 8));
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
const widths = new Map([["x", 2], ["u", 4], ["U", 8]]);
|
|
302
|
+
const width = widths.get(escape);
|
|
303
|
+
if (!width)
|
|
304
|
+
return unsupportedSyntax("python", `unsupported string escape \\${escape}`, location);
|
|
305
|
+
const digits = text.slice(index + 1, index + 1 + width);
|
|
306
|
+
if (digits.length != width || !/^[0-9A-Fa-f]+$/u.test(digits))
|
|
307
|
+
return unsupportedSyntax("python", "invalid string escape", location);
|
|
308
|
+
index += width;
|
|
309
|
+
const codePoint = Number.parseInt(digits, 16);
|
|
310
|
+
if (codePoint > 0x10FFFF || codePoint >= 0xD800 && codePoint <= 0xDFFF) {
|
|
311
|
+
return unsupportedSyntax("python", "invalid Unicode string escape", location);
|
|
312
|
+
}
|
|
313
|
+
decoded += String.fromCodePoint(codePoint);
|
|
314
|
+
}
|
|
315
|
+
if (!hasOnlyUnicodeScalars(decoded))
|
|
316
|
+
return unsupportedSyntax("python", "invalid Unicode string literal", location);
|
|
317
|
+
return decoded;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Converts one annotated assignment or plain assignment.
|
|
321
|
+
* @param {import("tree-sitter").SyntaxNode} node - Assignment node.
|
|
322
|
+
* @param {PythonContext} context - Comment association state.
|
|
323
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
324
|
+
* @param {string} filename - Source filename.
|
|
325
|
+
* @param {string} source - Complete source.
|
|
326
|
+
* @returns {import("../semantic/types.js").LocalStatement} Semantic local statement.
|
|
327
|
+
*/
|
|
328
|
+
function convertAssignment(node, context, visible, filename, source) {
|
|
329
|
+
const location = nodeLocation(node, filename, source);
|
|
330
|
+
const left = requiredField(node, "left", filename, source);
|
|
331
|
+
const right = requiredField(node, "right", filename, source);
|
|
332
|
+
const typeNode = node.childForFieldName("type");
|
|
333
|
+
if (left.type != "identifier")
|
|
334
|
+
return unsupportedSyntax("python", "non-identifier assignment target", nodeLocation(left, filename, source));
|
|
335
|
+
const name = identifier(left, typeNode ? "local" : "assignment target", filename, source);
|
|
336
|
+
const nameLocation = nodeLocation(left, filename, source);
|
|
337
|
+
const operator = operatorToken(node, new Set(["="]), filename, source);
|
|
338
|
+
if (!typeNode) {
|
|
339
|
+
if (!visible.has(name))
|
|
340
|
+
return missingType("python", `Local '${name}'`, location);
|
|
341
|
+
const target = withParserRanges({ kind: /** @type {const} */ ("IdentifierExpression"), location: nameLocation, name }, { name: nameLocation });
|
|
342
|
+
return withParserRanges({
|
|
343
|
+
expression: convertExpression(right, filename, source),
|
|
344
|
+
kind: /** @type {const} */ ("AssignmentStatement"),
|
|
345
|
+
location,
|
|
346
|
+
target
|
|
347
|
+
}, { operator: nodeLocation(operator, filename, source) });
|
|
348
|
+
}
|
|
349
|
+
const declaration = withParserRanges({
|
|
350
|
+
initializer: convertExpression(right, filename, source),
|
|
351
|
+
kind: /** @type {const} */ ("LocalDeclaration"),
|
|
352
|
+
location,
|
|
353
|
+
mutable: !takeImmutableMarker(node, context),
|
|
354
|
+
name,
|
|
355
|
+
type: convertType(typeNode, `Local '${name}'`, location, filename, source)
|
|
356
|
+
}, { name: nameLocation, operator: nodeLocation(operator, filename, source) });
|
|
357
|
+
visible.add(name);
|
|
358
|
+
return declaration;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Associates the exact immediately preceding immutable marker with a local.
|
|
362
|
+
* @param {import("tree-sitter").SyntaxNode} node - Local assignment.
|
|
363
|
+
* @param {PythonContext} context - Comment state.
|
|
364
|
+
* @returns {boolean} Whether the local is immutable.
|
|
365
|
+
*/
|
|
366
|
+
function takeImmutableMarker(node, context) {
|
|
367
|
+
const marker = context.comments.find((comment) => comment.text == immutableMarker &&
|
|
368
|
+
comment.endPosition.row + 1 == node.startPosition.row && comment.startPosition.column == node.startPosition.column);
|
|
369
|
+
if (!marker)
|
|
370
|
+
return false;
|
|
371
|
+
context.usedImmutableMarkers.add(marker);
|
|
372
|
+
return true;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Converts one statement.
|
|
376
|
+
* @param {import("tree-sitter").SyntaxNode} node - Statement node.
|
|
377
|
+
* @param {PythonContext} context - Comment state.
|
|
378
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
379
|
+
* @param {string} filename - Source filename.
|
|
380
|
+
* @param {string} source - Complete source.
|
|
381
|
+
* @returns {import("../semantic/types.js").Statement} Semantic statement.
|
|
382
|
+
*/
|
|
383
|
+
function convertStatement(node, context, visible, filename, source) {
|
|
384
|
+
const location = nodeLocation(node, filename, source);
|
|
385
|
+
if (node.type == "return_statement") {
|
|
386
|
+
const expressions = node.namedChildren.filter((child) => child.type != "comment");
|
|
387
|
+
if (expressions.length != 1)
|
|
388
|
+
return unsupportedSyntax("python", "return without one expression", location);
|
|
389
|
+
return { expression: convertExpression(expressions[0], filename, source), kind: "ReturnStatement", location };
|
|
390
|
+
}
|
|
391
|
+
if (node.type == "if_statement")
|
|
392
|
+
return convertIf(node, context, visible, filename, source);
|
|
393
|
+
if (node.type == "expression_statement") {
|
|
394
|
+
const expressions = node.namedChildren.filter((child) => child.type != "comment");
|
|
395
|
+
if (expressions.length != 1)
|
|
396
|
+
return unsupportedSyntax("python", node.type, location);
|
|
397
|
+
if (expressions[0].type == "assignment")
|
|
398
|
+
return convertAssignment(expressions[0], context, visible, filename, source);
|
|
399
|
+
return convertPrint(expressions[0], filename, source, location);
|
|
400
|
+
}
|
|
401
|
+
return unsupportedSyntax("python", node.type, location);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Converts the exact print(expression) statement.
|
|
405
|
+
* @param {import("tree-sitter").SyntaxNode} node - Expression statement value.
|
|
406
|
+
* @param {string} filename - Source filename.
|
|
407
|
+
* @param {string} source - Complete source.
|
|
408
|
+
* @param {import("../semantic/types.js").SourceLocation} location - Whole statement location.
|
|
409
|
+
* @returns {import("../semantic/types.js").PrintStatement} Print statement.
|
|
410
|
+
*/
|
|
411
|
+
function convertPrint(node, filename, source, location) {
|
|
412
|
+
if (node.type != "call")
|
|
413
|
+
return unsupportedSyntax("python", "entry expression other than print", nodeLocation(node, filename, source));
|
|
414
|
+
const callee = requiredField(node, "function", filename, source);
|
|
415
|
+
const argumentsNode = requiredField(node, "arguments", filename, source);
|
|
416
|
+
const arguments_ = argumentsNode.namedChildren.filter((child) => child.type != "comment");
|
|
417
|
+
if (callee.type != "identifier" || callee.text != "print" || argumentsNode.type != "argument_list" || arguments_.length != 1) {
|
|
418
|
+
return unsupportedSyntax("python", "print call shape", nodeLocation(node, filename, source));
|
|
419
|
+
}
|
|
420
|
+
return { expression: convertExpression(arguments_[0], filename, source), kind: "PrintStatement", location };
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Converts one if/elif/else node into nested semantic blocks.
|
|
424
|
+
* @param {import("tree-sitter").SyntaxNode} node - If or elif node.
|
|
425
|
+
* @param {PythonContext} context - Comment state.
|
|
426
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
427
|
+
* @param {string} filename - Source filename.
|
|
428
|
+
* @param {string} source - Complete source.
|
|
429
|
+
* @returns {import("../semantic/types.js").IfStatement} Semantic branch.
|
|
430
|
+
*/
|
|
431
|
+
function convertIf(node, context, visible, filename, source) {
|
|
432
|
+
const location = nodeLocation(node, filename, source);
|
|
433
|
+
const conditionNode = requiredField(node, "condition", filename, source);
|
|
434
|
+
const consequenceNode = requiredField(node, "consequence", filename, source);
|
|
435
|
+
const alternativeNodes = node.namedChildren.filter((_child, index) => node.fieldNameForNamedChild(index) == "alternative");
|
|
436
|
+
const alternate = convertAlternatives(alternativeNodes, context, new Set(visible), filename, source);
|
|
437
|
+
return {
|
|
438
|
+
...(alternate ? { alternate } : {}),
|
|
439
|
+
condition: convertExpression(conditionNode, filename, source),
|
|
440
|
+
consequent: convertBlock(consequenceNode, context, new Set(visible), filename, source),
|
|
441
|
+
kind: "IfStatement",
|
|
442
|
+
location
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Converts an else block or nests one elif inside its semantic alternate block.
|
|
447
|
+
* @param {import("tree-sitter").SyntaxNode[]} nodes - Ordered elif/else nodes.
|
|
448
|
+
* @param {PythonContext} context - Comment state.
|
|
449
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
450
|
+
* @param {string} filename - Source filename.
|
|
451
|
+
* @param {string} source - Complete source.
|
|
452
|
+
* @returns {import("../semantic/types.js").Block | undefined} Alternate block.
|
|
453
|
+
*/
|
|
454
|
+
function convertAlternatives(nodes, context, visible, filename, source) {
|
|
455
|
+
/** @type {import("../semantic/types.js").Block | undefined} */
|
|
456
|
+
let alternate;
|
|
457
|
+
for (let index = nodes.length - 1; index >= 0; index -= 1) {
|
|
458
|
+
const node = nodes[index];
|
|
459
|
+
if (node.type == "else_clause") {
|
|
460
|
+
if (alternate)
|
|
461
|
+
return unsupportedSyntax("python", "multiple else clauses", nodeLocation(node, filename, source));
|
|
462
|
+
alternate = convertBlock(requiredField(node, "body", filename, source), context, new Set(visible), filename, source);
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
if (node.type != "elif_clause")
|
|
466
|
+
return unsupportedSyntax("python", node.type, nodeLocation(node, filename, source));
|
|
467
|
+
const nested = convertIf(node, context, new Set(visible), filename, source);
|
|
468
|
+
if (alternate)
|
|
469
|
+
nested.alternate = alternate;
|
|
470
|
+
alternate = { kind: "Block", location: nodeLocation(node, filename, source), statements: [nested] };
|
|
471
|
+
}
|
|
472
|
+
return alternate;
|
|
473
|
+
}
|
|
474
|
+
/**
|
|
475
|
+
* Converts one indentation block and permits pass only as its sole executable node.
|
|
476
|
+
* @param {import("tree-sitter").SyntaxNode} node - Block node.
|
|
477
|
+
* @param {PythonContext} context - Comment state.
|
|
478
|
+
* @param {Set<string>} visible - Visible bindings in this lexical scope.
|
|
479
|
+
* @param {string} filename - Source filename.
|
|
480
|
+
* @param {string} source - Complete source.
|
|
481
|
+
* @returns {import("../semantic/types.js").Block} Semantic block.
|
|
482
|
+
*/
|
|
483
|
+
function convertBlock(node, context, visible, filename, source) {
|
|
484
|
+
const location = nodeLocation(node, filename, source);
|
|
485
|
+
if (node.type != "block")
|
|
486
|
+
return unsupportedSyntax("python", node.type, location);
|
|
487
|
+
const statements = node.namedChildren.filter((child) => child.type != "comment");
|
|
488
|
+
if (statements.some((statement) => statement.type == "pass_statement")) {
|
|
489
|
+
if (statements.length != 1)
|
|
490
|
+
return unsupportedSyntax("python", "pass with executable siblings", location);
|
|
491
|
+
return { kind: "Block", location, statements: [] };
|
|
492
|
+
}
|
|
493
|
+
return { kind: "Block", location, statements: statements.map((statement) => convertStatement(statement, context, visible, filename, source)) };
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Converts one exact synchronous top-level function.
|
|
497
|
+
* @param {import("tree-sitter").SyntaxNode} node - Function node.
|
|
498
|
+
* @param {PythonContext} context - Comment state.
|
|
499
|
+
* @param {string} filename - Source filename.
|
|
500
|
+
* @param {string} source - Complete source.
|
|
501
|
+
* @returns {import("../semantic/types.js").FunctionDeclaration} Semantic function.
|
|
502
|
+
*/
|
|
503
|
+
function convertFunction(node, context, filename, source) {
|
|
504
|
+
const location = nodeLocation(node, filename, source);
|
|
505
|
+
if (node.type != "function_definition" || node.children.some((child) => !child.isNamed && child.type == "async")) {
|
|
506
|
+
return unsupportedSyntax("python", node.type, location);
|
|
507
|
+
}
|
|
508
|
+
const typeParametersNode = node.childForFieldName("type_parameters");
|
|
509
|
+
if (typeParametersNode) {
|
|
510
|
+
return unsupportedSyntax("python", typeParametersNode.type, nodeLocation(typeParametersNode, filename, source));
|
|
511
|
+
}
|
|
512
|
+
const nameNode = requiredField(node, "name", filename, source);
|
|
513
|
+
const parametersNode = requiredField(node, "parameters", filename, source);
|
|
514
|
+
const returnNode = node.childForFieldName("return_type");
|
|
515
|
+
const bodyNode = requiredField(node, "body", filename, source);
|
|
516
|
+
const name = identifier(nameNode, "function", filename, source);
|
|
517
|
+
const parameterNodes = parametersNode.namedChildren.filter((child) => child.type != "comment");
|
|
518
|
+
if (parametersNode.children.some((child) => !child.isNamed && !["(", ")", ","].includes(child.type))) {
|
|
519
|
+
return unsupportedSyntax("python", "parameter separators", nodeLocation(parametersNode, filename, source));
|
|
520
|
+
}
|
|
521
|
+
const parameters = parameterNodes.map((parameterNode) => {
|
|
522
|
+
const parameterLocation = nodeLocation(parameterNode, filename, source);
|
|
523
|
+
if (parameterNode.type != "typed_parameter") {
|
|
524
|
+
if (parameterNode.type == "identifier")
|
|
525
|
+
return missingType("python", `Parameter '${parameterNode.text}'`, parameterLocation);
|
|
526
|
+
return unsupportedSyntax("python", parameterNode.type, parameterLocation);
|
|
527
|
+
}
|
|
528
|
+
const parameterNameNode = parameterNode.namedChildren.find((child) => child.type == "identifier");
|
|
529
|
+
const typeNode = parameterNode.childForFieldName("type");
|
|
530
|
+
if (!parameterNameNode)
|
|
531
|
+
return unsupportedSyntax("python", "parameter without identifier", parameterLocation);
|
|
532
|
+
const parameterName = identifier(parameterNameNode, "parameter", filename, source);
|
|
533
|
+
return withParserRanges({
|
|
534
|
+
kind: /** @type {const} */ ("Parameter"),
|
|
535
|
+
location: parameterLocation,
|
|
536
|
+
name: parameterName,
|
|
537
|
+
type: convertType(typeNode, `Parameter '${parameterName}'`, parameterLocation, filename, source)
|
|
538
|
+
}, { name: nodeLocation(parameterNameNode, filename, source) });
|
|
539
|
+
});
|
|
540
|
+
const visible = new Set(parameters.map((parameter) => parameter.name));
|
|
541
|
+
return withParserRanges({
|
|
542
|
+
body: convertBlock(bodyNode, context, visible, filename, source),
|
|
543
|
+
kind: "FunctionDeclaration",
|
|
544
|
+
location,
|
|
545
|
+
name,
|
|
546
|
+
parameters,
|
|
547
|
+
returnType: convertType(returnNode, `Function '${name}' return`, location, filename, source)
|
|
548
|
+
}, { name: nodeLocation(nameNode, filename, source) });
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Parses the strict Task 016 Python profile.
|
|
552
|
+
* @param {{filename: string, source: string}} input - Parser input.
|
|
553
|
+
* @returns {import("../semantic/types.js").SemanticModule} Semantic module.
|
|
554
|
+
*/
|
|
555
|
+
export function parsePython({ filename, source }) {
|
|
556
|
+
if (!hasOnlyUnicodeScalars(source)) {
|
|
557
|
+
const invalidOffset = firstLoneSurrogateOffset(source);
|
|
558
|
+
throw new SemantifoldDiagnostic({
|
|
559
|
+
code: "PARSE_ERROR",
|
|
560
|
+
language: "python",
|
|
561
|
+
location: locationFromOffsets(filename, source, invalidOffset, invalidOffset + 1),
|
|
562
|
+
message: "Python source contains an invalid lone UTF-16 surrogate."
|
|
563
|
+
});
|
|
564
|
+
}
|
|
565
|
+
let tree;
|
|
566
|
+
try {
|
|
567
|
+
tree = parser.parse(source);
|
|
568
|
+
}
|
|
569
|
+
catch (error) {
|
|
570
|
+
return parseFailure("python", error);
|
|
571
|
+
}
|
|
572
|
+
const root = tree.rootNode;
|
|
573
|
+
validateParserTree(root, filename, source);
|
|
574
|
+
if (root.type != "module")
|
|
575
|
+
throw new Error(`Tree-sitter returned Python root '${root.type}'.`);
|
|
576
|
+
const comments = root.descendantsOfType("comment");
|
|
577
|
+
const context = { comments, usedImmutableMarkers: new Set() };
|
|
578
|
+
const functions = [];
|
|
579
|
+
const entryNodes = [];
|
|
580
|
+
let sawEntry = false;
|
|
581
|
+
for (const node of root.namedChildren) {
|
|
582
|
+
if (node.type == "comment")
|
|
583
|
+
continue;
|
|
584
|
+
if (node.type == "function_definition" && !sawEntry)
|
|
585
|
+
functions.push(convertFunction(node, context, filename, source));
|
|
586
|
+
else {
|
|
587
|
+
sawEntry = true;
|
|
588
|
+
entryNodes.push(node);
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
const location = moduleLocation(filename, source);
|
|
592
|
+
const entryLocation = entryNodes.length == 0 ? location : locationFromOffsets(filename, source, bindingIndexToUtf16Offset(source, entryNodes[0].startIndex), bindingIndexToUtf16Offset(source, entryNodes.at(-1)?.endIndex ?? root.endIndex));
|
|
593
|
+
const entryVisible = new Set();
|
|
594
|
+
const entryHasPass = entryNodes.some((node) => node.type == "pass_statement");
|
|
595
|
+
if (entryHasPass && entryNodes.length != 1) {
|
|
596
|
+
return unsupportedSyntax("python", "top-level pass with executable siblings", entryLocation);
|
|
597
|
+
}
|
|
598
|
+
const entryBlock = {
|
|
599
|
+
kind: /** @type {const} */ ("Block"),
|
|
600
|
+
location: entryLocation,
|
|
601
|
+
statements: entryHasPass ? [] : entryNodes.map((node) => convertStatement(node, context, entryVisible, filename, source))
|
|
602
|
+
};
|
|
603
|
+
const unusedMarker = comments.find((comment) => comment.text == immutableMarker && !context.usedImmutableMarkers.has(comment));
|
|
604
|
+
if (unusedMarker)
|
|
605
|
+
return unsupportedSyntax("python", "unattached immutable marker", nodeLocation(unusedMarker, filename, source));
|
|
606
|
+
if (functions.length == 0)
|
|
607
|
+
return unsupportedSyntax("python", "module without a function", location);
|
|
608
|
+
return {
|
|
609
|
+
entryPoint: { body: entryBlock, kind: "EntryPoint", location: entryLocation },
|
|
610
|
+
functions,
|
|
611
|
+
kind: "Module",
|
|
612
|
+
location
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHl0aG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Zyb250ZW5kcy9weXRob24uanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQTtBQUNoQyxPQUFPLGNBQWMsTUFBTSxvQkFBb0IsQ0FBQTtBQUMvQyxPQUFPLEVBQUMsV0FBVyxFQUFFLFlBQVksRUFBRSxxQkFBcUIsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGtCQUFrQixDQUFBO0FBQ3BHLE9BQU8sRUFBQyxtQkFBbUIsRUFBRSxjQUFjLEVBQUUsMkJBQTJCLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUN4RyxPQUFPLEVBQUMsb0JBQW9CLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQTtBQUM3RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQTtBQUMxRCxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUM1RCxPQUFPLEVBQUMsdUJBQXVCLEVBQUMsTUFBTSxjQUFjLENBQUE7QUFFcEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQTtBQUUzQixNQUFNLENBQUMsV0FBVyxDQUFDLDZDQUE2QyxDQUFDLEVBQUMsc0JBQXVCLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBRTNHLE1BQU0sZUFBZSxHQUFHLDBCQUEwQixDQUFBO0FBQ2xELE1BQU0seUJBQXlCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDeEMsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxVQUFVO0lBQ3RHLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUk7SUFDeEcsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxNQUFNO0lBQ25HLE9BQU8sRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLO0NBQ2pFLENBQUMsQ0FBQTtBQUNGLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLENBQUM7SUFDL0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO0lBQ1osQ0FBQyxHQUFHLEVBQUUsVUFBVSxDQUFDO0lBQ2pCLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQztDQUNsQixDQUFDLENBQUE7QUFDRixNQUFNLG9CQUFvQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQ25DLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQztJQUNmLENBQUMsSUFBSSxFQUFFLFVBQVUsQ0FBQztJQUNsQixDQUFDLEdBQUcsRUFBRSxVQUFVLENBQUM7SUFDakIsQ0FBQyxJQUFJLEVBQUUsaUJBQWlCLENBQUM7SUFDekIsQ0FBQyxHQUFHLEVBQUUsYUFBYSxDQUFDO0lBQ3BCLENBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDO0NBQzdCLENBQUMsQ0FBQTtBQUVGLDJJQUEySTtBQUUzSTs7Ozs7OztHQU9HO0FBQ0gsU0FBUyx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsS0FBSztJQUM5QyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTTtRQUNoRSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxJQUFJLGtCQUFrQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksa0JBQWtCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDN0gsTUFBTSxJQUFJLFVBQVUsQ0FBQyxxQ0FBcUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtJQUNwRSxDQUFDO0lBQ0QsTUFBTSxVQUFVLEdBQUcsSUFBSSxXQUFXLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUE7SUFFMUUsT0FBTywyQkFBMkIsQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUE7QUFDeEQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLHdCQUF3QixDQUFDLE1BQU07SUFDdEMsS0FBSyxJQUFJLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3RELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUE7UUFFckMsSUFBSSxJQUFJLElBQUksTUFBTSxJQUFJLElBQUksSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNyQyxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQTtZQUV6QyxJQUFJLElBQUksSUFBSSxNQUFNLElBQUksSUFBSSxJQUFJLE1BQU07Z0JBQUUsS0FBSyxJQUFJLENBQUMsQ0FBQTs7Z0JBQzNDLE9BQU8sS0FBSyxDQUFBO1FBQ25CLENBQUM7YUFBTSxJQUFJLElBQUksSUFBSSxNQUFNLElBQUksSUFBSSxJQUFJLE1BQU07WUFBRSxPQUFPLEtBQUssQ0FBQTtJQUMzRCxDQUFDO0lBRUQsT0FBTyxDQUFDLENBQUMsQ0FBQTtBQUNYLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU07SUFDMUMsT0FBTyxtQkFBbUIsQ0FDeEIsUUFBUSxFQUNSLE1BQU0sRUFDTix5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUNsRCx5QkFBeUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUNqRCxDQUFBO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLGFBQWEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQ2xELE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQTtJQUUzQyxJQUFJLENBQUMsS0FBSztRQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksWUFBWSxLQUFLLEVBQUUsRUFBRSxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBRXJILE9BQU8sS0FBSyxDQUFBO0FBQ2QsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsa0JBQWtCLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQ2hELElBQUksSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbkMsTUFBTSxJQUFJLHFCQUFxQixDQUFDO1lBQzlCLElBQUksRUFBRSxhQUFhO1lBQ25CLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLFFBQVEsRUFBRSxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7WUFDOUMsT0FBTyxFQUFFLHVCQUF1QixJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLFVBQVUsbUJBQW1CLElBQUksQ0FBQyxJQUFJLElBQUk7U0FDMUcsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLEtBQUssSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUN4RCxNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRS9CLElBQUksQ0FBQyxLQUFLO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyw2QkFBNkIsS0FBSyxPQUFPLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFBO1FBQ2xGLGtCQUFrQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDN0MsQ0FBQztBQUNILENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBUyxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTTtJQUM5QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBO0lBRXRCLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxZQUFZLElBQUkseUJBQXlCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxFQUFFLENBQUM7UUFDdkcsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsR0FBRyxJQUFJLGdCQUFnQixJQUFJLEdBQUcsRUFBRSxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBQzFHLENBQUM7SUFFRCxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsV0FBVyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQ2pFLElBQUksQ0FBQyxJQUFJO1FBQUUsT0FBTyxXQUFXLENBQUMsUUFBUSxFQUFFLE9BQU8sRUFBRSxhQUFhLENBQUMsQ0FBQTtJQUMvRCxNQUFNLFlBQVksR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUN6RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQTtJQUU5RSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksTUFBTSxJQUFJLFFBQVEsQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksWUFBWTtRQUNqRixDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RGLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLCtCQUErQixFQUFFLFlBQVksQ0FBQyxDQUFBO0lBQ25GLENBQUM7SUFFRCxPQUFPLHVCQUF1QixDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxhQUFhLEVBQUUsWUFBWSxDQUFDLENBQUE7QUFDbEcsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxTQUFTLGFBQWEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQ3RELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtJQUUzRixJQUFJLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQztRQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksV0FBVyxFQUFFLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7SUFFekgsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDbEIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQy9DLE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRXJELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSwwQkFBMEIsRUFBRSxDQUFDO1FBQzVDLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFBO1FBRWpGLElBQUksV0FBVyxDQUFDLE1BQU0sSUFBSSxDQUFDO1lBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUVwRixPQUFPLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDNUQsQ0FBQztJQUNELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUM5QixNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFFNUQsT0FBTyxnQkFBZ0IsQ0FBQyxFQUFDLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBQyxFQUFFLEVBQUMsSUFBSSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7SUFDbEgsQ0FBQztJQUNELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUMzQixJQUFJLEtBQUssQ0FBQTtRQUVULElBQUksQ0FBQztZQUNILEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdkQsQ0FBQztRQUFDLE1BQU0sQ0FBQztZQUNQLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLGlCQUFpQixFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ2pFLENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7WUFBRSxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSwwQkFBMEIsRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUUxRyxPQUFPLGdCQUFnQixDQUFDLEVBQUMsSUFBSSxFQUFFLG9CQUFvQixDQUFDLENBQUMsZ0JBQWdCLENBQUMsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFDLEVBQUUsRUFBQyxPQUFPLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtJQUNoSCxDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ2hELE9BQU8sZ0JBQWdCLENBQUMsRUFBQyxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsSUFBSSxDQUFDLElBQUksSUFBSSxNQUFNLEVBQUMsRUFBRSxFQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO0lBQ3JJLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksUUFBUSxFQUFFLENBQUM7UUFDMUIsT0FBTyxnQkFBZ0IsQ0FBQyxFQUFDLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUMsRUFBRTtZQUM3SCxPQUFPLEVBQUUsUUFBUTtTQUNsQixDQUFDLENBQUE7SUFDSixDQUFDO0lBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLHFCQUFxQjtRQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLCtCQUErQixFQUFFLFFBQVEsQ0FBQyxDQUFBO0lBQ3JILElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sV0FBVyxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUNyRSxNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDdEUsTUFBTSxRQUFRLEdBQUcsb0JBQW9CLENBQUMsZ0JBQWdCLENBQUM7WUFDckQsSUFBSSxFQUFFLGlCQUFpQjtZQUN2QixRQUFRO1lBQ1IsT0FBTyxFQUFFLGlCQUFpQixDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO1NBQzFELEVBQUUsRUFBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBRW5FLE9BQU8sd0RBQXdELENBQUMsRUFBQyxzQkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO0lBQ3JHLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksY0FBYyxFQUFFLENBQUM7UUFDaEMsTUFBTSxXQUFXLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3JFLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUN4RSxNQUFNLFFBQVEsR0FBRyxvQkFBb0IsQ0FBQyxnQkFBZ0IsQ0FBQztZQUNyRCxJQUFJLEVBQUUsaUJBQWlCO1lBQ3ZCLFFBQVE7WUFDUixPQUFPLEVBQUUsaUJBQWlCLENBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7U0FDMUQsRUFBRSxFQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFFaEUsT0FBTyx3REFBd0QsQ0FBQyxFQUFDLHNCQUF1QixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUE7SUFDckcsQ0FBQztJQUNELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxpQkFBaUIsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLHFCQUFxQixJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksa0JBQWtCLEVBQUUsQ0FBQztRQUM1RyxNQUFNLGtCQUFrQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLFNBQVMsQ0FBQyxDQUFBO1FBQ3hGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUN4RSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxDQUFDLElBQUksa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFFMUUsSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ3BGLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksaUJBQWlCLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLHFCQUFxQjtZQUN2RyxDQUFDLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQ2xFLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ2xGLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBRTdDLElBQUksQ0FBQyxPQUFPLElBQUksa0JBQWtCLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQy9DLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDekQsQ0FBQztRQUNELE1BQU0sUUFBUSxHQUFHLG9CQUFvQixDQUFDLGdCQUFnQixDQUFDO1lBQ3JELElBQUksRUFBRSxrQkFBa0I7WUFDeEIsSUFBSSxFQUFFLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO1lBQ25ELFFBQVE7WUFDUixLQUFLLEVBQUUsaUJBQWlCLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7U0FDdEQsRUFBRSxFQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBQyxDQUFDLEVBQUUsa0VBQWtFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFBO1FBRXZJLE9BQU8sd0RBQXdELENBQUMsRUFBQyxzQkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFBO0lBQ3JHLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksTUFBTSxFQUFFLENBQUM7UUFDeEIsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBQ3BFLE1BQU0sYUFBYSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUV4RSxJQUFJLFVBQVUsQ0FBQyxJQUFJLElBQUksWUFBWSxJQUFJLGFBQWEsQ0FBQyxJQUFJLElBQUksZUFBZSxFQUFFLENBQUM7WUFDN0UsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsY0FBYyxFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQzlELENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDakUsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDO2FBQ3RGLEdBQUcsQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFLENBQUMsaUJBQWlCLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO1FBRW5FLE9BQU8sZ0JBQWdCLENBQUMsRUFBQyxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFLFFBQVEsRUFBQyxFQUFFO1lBQ2hILE1BQU0sRUFBRSxZQUFZLENBQUMsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7U0FDbkQsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVELE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUE7QUFDekQsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTTtJQUMxQyxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUNyRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFBO0lBQ3RCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVyQixJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksSUFBSSxLQUFLLElBQUksR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsS0FBSyxHQUFHLEtBQUssR0FBRyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDM0csT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsa0NBQWtDLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFDbEYsQ0FBQztJQUNELElBQUksT0FBTyxHQUFHLEVBQUUsQ0FBQTtJQUVoQixLQUFLLElBQUksS0FBSyxHQUFHLENBQUMsRUFBRSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQ3hELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUU3QixJQUFJLFNBQVMsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN0QixPQUFPLElBQUksU0FBUyxDQUFBO1lBQ3BCLFNBQVE7UUFDVixDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFFNUIsSUFBSSxNQUFNLEtBQUssU0FBUztZQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLHVCQUF1QixFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQy9GLE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxDQUFDO1lBQ3JCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQztZQUM5RixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUM7U0FDdEMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDdkIsT0FBTyxJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUE7WUFDN0IsU0FBUTtRQUNWLENBQUM7UUFDRCxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUMxQixJQUFJLE1BQU0sR0FBRyxNQUFNLENBQUE7WUFFbkIsT0FBTyxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQTtZQUN6RixPQUFPLElBQUksTUFBTSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQzNELFNBQVE7UUFDVixDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDdEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUVoQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLCtCQUErQixNQUFNLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUNqRyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQTtRQUN2RCxJQUFJLE1BQU0sQ0FBQyxNQUFNLElBQUksS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLHVCQUF1QixFQUFFLFFBQVEsQ0FBQyxDQUFBO1FBQ3BJLEtBQUssSUFBSSxLQUFLLENBQUE7UUFDZCxNQUFNLFNBQVMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUU3QyxJQUFJLFNBQVMsR0FBRyxRQUFRLElBQUksU0FBUyxJQUFJLE1BQU0sSUFBSSxTQUFTLElBQUksTUFBTSxFQUFFLENBQUM7WUFDdkUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsK0JBQStCLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDL0UsQ0FBQztRQUNELE9BQU8sSUFBSSxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFBO0lBQzVDLENBQUM7SUFFRCxJQUFJLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDO1FBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsZ0NBQWdDLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFFbkgsT0FBTyxPQUFPLENBQUE7QUFDaEIsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTTtJQUNqRSxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUNyRCxNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDMUQsTUFBTSxLQUFLLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQzVELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUUvQyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksWUFBWTtRQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLGtDQUFrQyxFQUFFLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7SUFDM0ksTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsbUJBQW1CLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3pGLE1BQU0sWUFBWSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3pELE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUV0RSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDZCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUM7WUFBRSxPQUFPLFdBQVcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxJQUFJLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUNqRixNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxFQUFDLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLHNCQUFzQixDQUFDLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUMsRUFBRSxFQUFDLElBQUksRUFBRSxZQUFZLEVBQUMsQ0FBQyxDQUFBO1FBRTFJLE9BQU8sZ0JBQWdCLENBQUM7WUFDdEIsVUFBVSxFQUFFLGlCQUFpQixDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO1lBQ3RELElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLHFCQUFxQixDQUFDO1lBQ2xELFFBQVE7WUFDUixNQUFNO1NBQ1AsRUFBRSxFQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsUUFBUSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBQyxDQUFDLENBQUE7SUFDMUQsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLGdCQUFnQixDQUFDO1FBQ25DLFdBQVcsRUFBRSxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQztRQUN2RCxJQUFJLEVBQUUsb0JBQW9CLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQztRQUMvQyxRQUFRO1FBQ1IsT0FBTyxFQUFFLENBQUMsbUJBQW1CLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQztRQUM1QyxJQUFJO1FBQ0osSUFBSSxFQUFFLFdBQVcsQ0FBQyxRQUFRLEVBQUUsVUFBVSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQztLQUMzRSxFQUFFLEVBQUMsSUFBSSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUMsQ0FBQyxDQUFBO0lBRTVFLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUE7SUFFakIsT0FBTyxXQUFXLENBQUE7QUFDcEIsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsT0FBTztJQUN4QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxlQUFlO1FBQy9FLE9BQU8sQ0FBQyxXQUFXLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsSUFBSSxPQUFPLENBQUMsYUFBYSxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBRXJILElBQUksQ0FBQyxNQUFNO1FBQUUsT0FBTyxLQUFLLENBQUE7SUFDekIsT0FBTyxDQUFDLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUV4QyxPQUFPLElBQUksQ0FBQTtBQUNiLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU07SUFDaEUsTUFBTSxRQUFRLEdBQUcsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFFckQsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGtCQUFrQixFQUFFLENBQUM7UUFDcEMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDLENBQUE7UUFFakYsSUFBSSxXQUFXLENBQUMsTUFBTSxJQUFJLENBQUM7WUFBRSxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSwrQkFBK0IsRUFBRSxRQUFRLENBQUMsQ0FBQTtRQUUxRyxPQUFPLEVBQUMsVUFBVSxFQUFFLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUUsSUFBSSxFQUFFLGlCQUFpQixFQUFFLFFBQVEsRUFBQyxDQUFBO0lBQzdHLENBQUM7SUFDRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksY0FBYztRQUFFLE9BQU8sU0FBUyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUMzRixJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksc0JBQXNCLEVBQUUsQ0FBQztRQUN4QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQTtRQUVqRixJQUFJLFdBQVcsQ0FBQyxNQUFNLElBQUksQ0FBQztZQUFFLE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFDcEYsSUFBSSxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLFlBQVk7WUFBRSxPQUFPLGlCQUFpQixDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUVySCxPQUFPLFlBQVksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUNqRSxDQUFDO0lBRUQsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtBQUN6RCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILFNBQVMsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFFBQVE7SUFDcEQsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLE1BQU07UUFBRSxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxtQ0FBbUMsRUFBRSxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBQ3RJLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUNoRSxNQUFNLGFBQWEsR0FBRyxhQUFhLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDeEUsTUFBTSxVQUFVLEdBQUcsYUFBYSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLElBQUksU0FBUyxDQUFDLENBQUE7SUFFekYsSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLFlBQVksSUFBSSxNQUFNLENBQUMsSUFBSSxJQUFJLE9BQU8sSUFBSSxhQUFhLENBQUMsSUFBSSxJQUFJLGVBQWUsSUFBSSxVQUFVLENBQUMsTUFBTSxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzdILE9BQU8saUJBQWlCLENBQUMsUUFBUSxFQUFFLGtCQUFrQixFQUFFLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7SUFDOUYsQ0FBQztJQUVELE9BQU8sRUFBQyxVQUFVLEVBQUUsaUJBQWlCLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsUUFBUSxFQUFDLENBQUE7QUFDM0csQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxTQUFTLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU07SUFDekQsTUFBTSxRQUFRLEdBQUcsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDckQsTUFBTSxhQUFhLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ3hFLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUM1RSxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLEtBQUssQ0FBQyxJQUFJLGFBQWEsQ0FBQyxDQUFBO0lBQzFILE1BQU0sU0FBUyxHQUFHLG1CQUFtQixDQUFDLGdCQUFnQixFQUFFLE9BQU8sRUFBRSxJQUFJLEdBQUcsQ0FBQyxPQUFPLENBQUMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFFcEcsT0FBTztRQUNMLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUMsU0FBUyxFQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNqQyxTQUFTLEVBQUUsaUJBQWlCLENBQUMsYUFBYSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7UUFDN0QsVUFBVSxFQUFFLFlBQVksQ0FBQyxlQUFlLEVBQUUsT0FBTyxFQUFFLElBQUksR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7UUFDdEYsSUFBSSxFQUFFLGFBQWE7UUFDbkIsUUFBUTtLQUNULENBQUE7QUFDSCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFTLG1CQUFtQixDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQ3BFLCtEQUErRDtJQUMvRCxJQUFJLFNBQVMsQ0FBQTtJQUViLEtBQUssSUFBSSxLQUFLLEdBQUcsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDMUQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBRXpCLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxhQUFhLEVBQUUsQ0FBQztZQUMvQixJQUFJLFNBQVM7Z0JBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsdUJBQXVCLEVBQUUsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtZQUNoSCxTQUFTLEdBQUcsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1lBQ3BILFNBQVE7UUFDVixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLGFBQWE7WUFBRSxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDbkgsTUFBTSxNQUFNLEdBQUcsU0FBUyxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO1FBRTNFLElBQUksU0FBUztZQUFFLE1BQU0sQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFBO1FBQzNDLFNBQVMsR0FBRyxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxFQUFFLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxFQUFDLENBQUE7SUFDbkcsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQVMsWUFBWSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNO0lBQzVELE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBRXJELElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxPQUFPO1FBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUNqRixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQTtJQUVoRixJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLElBQUksZ0JBQWdCLENBQUMsRUFBRSxDQUFDO1FBQ3ZFLElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxDQUFDO1lBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsK0JBQStCLEVBQUUsUUFBUSxDQUFDLENBQUE7UUFFekcsT0FBTyxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUMsQ0FBQTtJQUNsRCxDQUFDO0lBRUQsT0FBTyxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsRUFBQyxDQUFBO0FBQzlJLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsU0FBUyxlQUFlLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTTtJQUN0RCxNQUFNLFFBQVEsR0FBRyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUVyRCxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUkscUJBQXFCLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLE9BQU8sQ0FBQyxFQUFFLENBQUM7UUFDakgsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQTtJQUN6RCxDQUFDO0lBQ0QsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsaUJBQWlCLENBQUMsQ0FBQTtJQUVwRSxJQUFJLGtCQUFrQixFQUFFLENBQUM7UUFDdkIsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsa0JBQWtCLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxrQkFBa0IsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUNqSCxDQUFDO0lBQ0QsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQzlELE1BQU0sY0FBYyxHQUFHLGFBQWEsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUMxRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDeEQsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQzlELE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUMvRCxNQUFNLGNBQWMsR0FBRyxjQUFjLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsQ0FBQTtJQUU5RixJQUFJLGNBQWMsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDckcsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsc0JBQXNCLEVBQUUsWUFBWSxDQUFDLGNBQWMsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQTtJQUM1RyxDQUFDO0lBQ0QsTUFBTSxVQUFVLEdBQUcsY0FBYyxDQUFDLEdBQUcsQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO1FBQ3RELE1BQU0saUJBQWlCLEdBQUcsWUFBWSxDQUFDLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFFdkUsSUFBSSxhQUFhLENBQUMsSUFBSSxJQUFJLGlCQUFpQixFQUFFLENBQUM7WUFDNUMsSUFBSSxhQUFhLENBQUMsSUFBSSxJQUFJLFlBQVk7Z0JBQUUsT0FBTyxXQUFXLENBQUMsUUFBUSxFQUFFLGNBQWMsYUFBYSxDQUFDLElBQUksR0FBRyxFQUFFLGlCQUFpQixDQUFDLENBQUE7WUFFNUgsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxDQUFBO1FBQzNFLENBQUM7UUFDRCxNQUFNLGlCQUFpQixHQUFHLGFBQWEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQyxDQUFBO1FBQ2pHLE1BQU0sUUFBUSxHQUFHLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUV4RCxJQUFJLENBQUMsaUJBQWlCO1lBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsOEJBQThCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQTtRQUM3RyxNQUFNLGFBQWEsR0FBRyxVQUFVLENBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtRQUVsRixPQUFPLGdCQUFnQixDQUFDO1lBQ3RCLElBQUksRUFBRSxvQkFBb0IsQ0FBQyxDQUFDLFdBQVcsQ0FBQztZQUN4QyxRQUFRLEVBQUUsaUJBQWlCO1lBQzNCLElBQUksRUFBRSxhQUFhO1lBQ25CLElBQUksRUFBRSxXQUFXLENBQUMsUUFBUSxFQUFFLGNBQWMsYUFBYSxHQUFHLEVBQUUsaUJBQWlCLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQztTQUNqRyxFQUFFLEVBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUMsQ0FBQyxDQUFBO0lBQy9ELENBQUMsQ0FBQyxDQUFBO0lBRUYsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7SUFFdEUsT0FBTyxnQkFBZ0IsQ0FBQztRQUN0QixJQUFJLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUM7UUFDaEUsSUFBSSxFQUFFLHFCQUFxQjtRQUMzQixRQUFRO1FBQ1IsSUFBSTtRQUNKLFVBQVU7UUFDVixVQUFVLEVBQUUsV0FBVyxDQUFDLFVBQVUsRUFBRSxhQUFhLElBQUksVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDO0tBQzdGLEVBQUUsRUFBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxDQUFDLEVBQUMsQ0FBQyxDQUFBO0FBQ3RELENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxVQUFVLFdBQVcsQ0FBQyxFQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUM7SUFDNUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDbkMsTUFBTSxhQUFhLEdBQUcsd0JBQXdCLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFdEQsTUFBTSxJQUFJLHFCQUFxQixDQUFDO1lBQzlCLElBQUksRUFBRSxhQUFhO1lBQ25CLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxFQUFFLGFBQWEsRUFBRSxhQUFhLEdBQUcsQ0FBQyxDQUFDO1lBQ2pGLE9BQU8sRUFBRSwwREFBMEQ7U0FDcEUsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUNELElBQUksSUFBSSxDQUFBO0lBRVIsSUFBSSxDQUFDO1FBQ0gsSUFBSSxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDN0IsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLFlBQVksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUE7SUFDdEMsQ0FBQztJQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUE7SUFFMUIsa0JBQWtCLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQTtJQUMxQyxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksUUFBUTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMscUNBQXFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFBO0lBRTlGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUNsRCxNQUFNLE9BQU8sR0FBRyxFQUFDLFFBQVEsRUFBRSxvQkFBb0IsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFDLENBQUE7SUFDM0QsTUFBTSxTQUFTLEdBQUcsRUFBRSxDQUFBO0lBQ3BCLE1BQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQTtJQUNyQixJQUFJLFFBQVEsR0FBRyxLQUFLLENBQUE7SUFFcEIsS0FBSyxNQUFNLElBQUksSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDdEMsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLFNBQVM7WUFBRSxTQUFRO1FBQ3BDLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxxQkFBcUIsSUFBSSxDQUFDLFFBQVE7WUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO2FBQ2hILENBQUM7WUFDSixRQUFRLEdBQUcsSUFBSSxDQUFBO1lBQ2YsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN2QixDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLGNBQWMsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUE7SUFDakQsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsbUJBQW1CLENBQzNFLFFBQVEsRUFDUixNQUFNLEVBQ04seUJBQXlCLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsRUFDM0QseUJBQXlCLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxRQUFRLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUNoRixDQUFBO0lBQ0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQUUsQ0FBQTtJQUM5QixNQUFNLFlBQVksR0FBRyxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLGdCQUFnQixDQUFDLENBQUE7SUFFN0UsSUFBSSxZQUFZLElBQUksVUFBVSxDQUFDLE1BQU0sSUFBSSxDQUFDLEVBQUUsQ0FBQztRQUMzQyxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSx5Q0FBeUMsRUFBRSxhQUFhLENBQUMsQ0FBQTtJQUM5RixDQUFDO0lBQ0QsTUFBTSxVQUFVLEdBQUc7UUFDakIsSUFBSSxFQUFFLG9CQUFvQixDQUFDLENBQUMsT0FBTyxDQUFDO1FBQ3BDLFFBQVEsRUFBRSxhQUFhO1FBQ3ZCLFVBQVUsRUFBRSxZQUFZLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0tBQzFILENBQUE7SUFDRCxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLGVBQWUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQTtJQUU5SCxJQUFJLFlBQVk7UUFBRSxPQUFPLGlCQUFpQixDQUFDLFFBQVEsRUFBRSw2QkFBNkIsRUFBRSxZQUFZLENBQUMsWUFBWSxFQUFFLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFBO0lBQ2pJLElBQUksU0FBUyxDQUFDLE1BQU0sSUFBSSxDQUFDO1FBQUUsT0FBTyxpQkFBaUIsQ0FBQyxRQUFRLEVBQUUsMkJBQTJCLEVBQUUsUUFBUSxDQUFDLENBQUE7SUFFcEcsT0FBTztRQUNMLFVBQVUsRUFBRSxFQUFDLElBQUksRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFDO1FBQzNFLFNBQVM7UUFDVCxJQUFJLEVBQUUsUUFBUTtRQUNkLFFBQVE7S0FDVCxDQUFBO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgUGFyc2VyIGZyb20gXCJ0cmVlLXNpdHRlclwiXG5pbXBvcnQgUHl0aG9uTGFuZ3VhZ2UgZnJvbSBcInRyZWUtc2l0dGVyLXB5dGhvblwiXG5pbXBvcnQge21pc3NpbmdUeXBlLCBwYXJzZUZhaWx1cmUsIFNlbWFudGlmb2xkRGlhZ25vc3RpYywgdW5zdXBwb3J0ZWRTeW50YXh9IGZyb20gXCIuLi9kaWFnbm9zdGljLmpzXCJcbmltcG9ydCB7bG9jYXRpb25Gcm9tT2Zmc2V0cywgbW9kdWxlTG9jYXRpb24sIHV0ZjhCeXRlT2Zmc2V0VG9VdGYxNk9mZnNldH0gZnJvbSBcIi4uL3NlbWFudGljL2xvY2F0aW9uLmpzXCJcbmltcG9ydCB7d2l0aEFkYXB0ZWRPcGVyYXRpb259IGZyb20gXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIlxuaW1wb3J0IHt3aXRoUGFyc2VyUmFuZ2VzfSBmcm9tIFwiLi4vc2VtYW50aWMvcHJvdmVuYW5jZS5qc1wiXG5pbXBvcnQge2hhc09ubHlVbmljb2RlU2NhbGFyc30gZnJvbSBcIi4uL3NlbWFudGljL3NjYWxhcnMuanNcIlxuaW1wb3J0IHtyZXF1aXJlU291cmNlU2NhbGFyVHlwZX0gZnJvbSBcIi4vc2NhbGFycy5qc1wiXG5cbmNvbnN0IHBhcnNlciA9IG5ldyBQYXJzZXIoKVxuXG5wYXJzZXIuc2V0TGFuZ3VhZ2UoLyoqIEB0eXBlIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5MYW5ndWFnZX0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKFB5dGhvbkxhbmd1YWdlKSkpXG5cbmNvbnN0IGltbXV0YWJsZU1hcmtlciA9IFwiIyBAc2VtYW50aWZvbGQtaW1tdXRhYmxlXCJcbmNvbnN0IHB5dGhvblJlc2VydmVkSWRlbnRpZmllcnMgPSBuZXcgU2V0KFtcbiAgXCJGYWxzZVwiLCBcIk5vbmVcIiwgXCJUcnVlXCIsIFwiYW5kXCIsIFwiYXNcIiwgXCJhc3NlcnRcIiwgXCJhc3luY1wiLCBcImF3YWl0XCIsIFwiYnJlYWtcIiwgXCJjYXNlXCIsIFwiY2xhc3NcIiwgXCJjb250aW51ZVwiLFxuICBcImRlZlwiLCBcImRlbFwiLCBcImVsaWZcIiwgXCJlbHNlXCIsIFwiZXhjZXB0XCIsIFwiZXhlY1wiLCBcImZpbmFsbHlcIiwgXCJmb3JcIiwgXCJmcm9tXCIsIFwiZ2xvYmFsXCIsIFwiaWZcIiwgXCJpbXBvcnRcIiwgXCJpblwiLFxuICBcImlzXCIsIFwibGFtYmRhXCIsIFwibWF0Y2hcIiwgXCJub25sb2NhbFwiLCBcIm5vdFwiLCBcIm9yXCIsIFwicGFzc1wiLCBcInByaW50XCIsIFwicmFpc2VcIiwgXCJyZXR1cm5cIiwgXCJ0cnlcIiwgXCJ0eXBlXCIsXG4gIFwid2hpbGVcIiwgXCJ3aXRoXCIsIFwieWllbGRcIiwgXCJfXCIsIFwiX19kZWJ1Z19fXCIsIFwiaW50XCIsIFwiYm9vbFwiLCBcInN0clwiXG5dKVxuY29uc3QgYmluYXJ5T3BlcmF0aW9ucyA9IG5ldyBNYXAoW1xuICBbXCIrXCIsIFwiQWRkXCJdLFxuICBbXCItXCIsIFwiU3VidHJhY3RcIl0sXG4gIFtcIipcIiwgXCJNdWx0aXBseVwiXVxuXSlcbmNvbnN0IGNvbXBhcmlzb25PcGVyYXRpb25zID0gbmV3IE1hcChbXG4gIFtcIj09XCIsIFwiRXF1YWxcIl0sXG4gIFtcIiE9XCIsIFwiTm90RXF1YWxcIl0sXG4gIFtcIjxcIiwgXCJMZXNzVGhhblwiXSxcbiAgW1wiPD1cIiwgXCJMZXNzVGhhbk9yRXF1YWxcIl0sXG4gIFtcIj5cIiwgXCJHcmVhdGVyVGhhblwiXSxcbiAgW1wiPj1cIiwgXCJHcmVhdGVyVGhhbk9yRXF1YWxcIl1cbl0pXG5cbi8qKiBAdHlwZWRlZiB7e2NvbW1lbnRzOiBpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlW10sIHVzZWRJbW11dGFibGVNYXJrZXJzOiBTZXQ8aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZT59fSBQeXRob25Db250ZXh0ICovXG5cbi8qKlxuICogUm91dGVzIHRoZSBiaW5kaW5nJ3MgVVRGLTE2IGluZGV4IHRocm91Z2ggdGhlIHNoYXJlZCBVVEYtOCBieXRlIGNvbnZlcnRlci5cbiAqIG5vZGUtdHJlZS1zaXR0ZXIgcGFyc2VzIEphdmFTY3JpcHQgc3RyaW5ncyBhcyBVVEYtMTZMRSBhbmQgZXhwb3NlcyBjb2RlLXVuaXRcbiAqIGluZGV4ZXMgZXZlbiB0aG91Z2ggdGhlIGdyYW1tYXIncyBuYXRpdmUgY29vcmRpbmF0ZSBjb250cmFjdCBpcyBieXRlLWJhc2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIEJpbmRpbmcgVVRGLTE2IGluZGV4LlxuICogQHJldHVybnMge251bWJlcn0gVmVyaWZpZWQgVVRGLTE2IG9mZnNldC5cbiAqL1xuZnVuY3Rpb24gYmluZGluZ0luZGV4VG9VdGYxNk9mZnNldChzb3VyY2UsIGluZGV4KSB7XG4gIGlmICghTnVtYmVyLmlzSW50ZWdlcihpbmRleCkgfHwgaW5kZXggPCAwIHx8IGluZGV4ID4gc291cmNlLmxlbmd0aCB8fFxuICAgIGluZGV4ID4gMCAmJiBpbmRleCA8IHNvdXJjZS5sZW5ndGggJiYgL1tcXHVEODAwLVxcdURCRkZdL3UudGVzdChzb3VyY2VbaW5kZXggLSAxXSkgJiYgL1tcXHVEQzAwLVxcdURGRkZdL3UudGVzdChzb3VyY2VbaW5kZXhdKSkge1xuICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBJbnZhbGlkIFRyZWUtc2l0dGVyIHNvdXJjZSBpbmRleDogJHtpbmRleH1gKVxuICB9XG4gIGNvbnN0IGJ5dGVPZmZzZXQgPSBuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoc291cmNlLnNsaWNlKDAsIGluZGV4KSkubGVuZ3RoXG5cbiAgcmV0dXJuIHV0ZjhCeXRlT2Zmc2V0VG9VdGYxNk9mZnNldChzb3VyY2UsIGJ5dGVPZmZzZXQpXG59XG5cbi8qKlxuICogRmluZHMgdGhlIGZpcnN0IHVucGFpcmVkIFVURi0xNiBzdXJyb2dhdGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge251bWJlcn0gSW52YWxpZCBvZmZzZXQsIG9yIC0xLlxuICovXG5mdW5jdGlvbiBmaXJzdExvbmVTdXJyb2dhdGVPZmZzZXQoc291cmNlKSB7XG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBzb3VyY2UubGVuZ3RoOyBpbmRleCArPSAxKSB7XG4gICAgY29uc3QgdW5pdCA9IHNvdXJjZS5jaGFyQ29kZUF0KGluZGV4KVxuXG4gICAgaWYgKHVuaXQgPj0gMHhEODAwICYmIHVuaXQgPD0gMHhEQkZGKSB7XG4gICAgICBjb25zdCBuZXh0ID0gc291cmNlLmNoYXJDb2RlQXQoaW5kZXggKyAxKVxuXG4gICAgICBpZiAobmV4dCA+PSAweERDMDAgJiYgbmV4dCA8PSAweERGRkYpIGluZGV4ICs9IDFcbiAgICAgIGVsc2UgcmV0dXJuIGluZGV4XG4gICAgfSBlbHNlIGlmICh1bml0ID49IDB4REMwMCAmJiB1bml0IDw9IDB4REZGRikgcmV0dXJuIGluZGV4XG4gIH1cblxuICByZXR1cm4gLTFcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIFRyZWUtc2l0dGVyIGJ5dGUgcmFuZ2UgaW50byBTZW1hbnRpZm9sZCdzIFVURi0xNiBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFBhcnNlciBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gRXhhY3QgbG9jYXRpb24uXG4gKi9cbmZ1bmN0aW9uIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIHJldHVybiBsb2NhdGlvbkZyb21PZmZzZXRzKFxuICAgIGZpbGVuYW1lLFxuICAgIHNvdXJjZSxcbiAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHNvdXJjZSwgbm9kZS5zdGFydEluZGV4KSxcbiAgICBiaW5kaW5nSW5kZXhUb1V0ZjE2T2Zmc2V0KHNvdXJjZSwgbm9kZS5lbmRJbmRleClcbiAgKVxufVxuXG4vKipcbiAqIFJlcXVpcmVzIG9uZSBwYXJzZXIgZmllbGQuXG4gKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBGaWVsZCBvd25lci5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWVsZCAtIEdyYW1tYXIgZmllbGQgbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gRmllbGQgbm9kZS5cbiAqL1xuZnVuY3Rpb24gcmVxdWlyZWRGaWVsZChub2RlLCBmaWVsZCwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBjaGlsZCA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoZmllbGQpXG5cbiAgaWYgKCFjaGlsZCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIGAke25vZGUudHlwZX0gd2l0aG91dCAke2ZpZWxkfWAsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcblxuICByZXR1cm4gY2hpbGRcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgZXZlcnkgbmFtZWQgYW5kIGFub255bW91cyBwYXJzZXIgY2hpbGQgYW5kIHJlamVjdHMgcmVjb3ZlcnkuXG4gKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBDdXJyZW50IHBhcnNlciBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVBhcnNlclRyZWUobm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAobm9kZS5pc0Vycm9yIHx8IG5vZGUuaXNNaXNzaW5nKSB7XG4gICAgdGhyb3cgbmV3IFNlbWFudGlmb2xkRGlhZ25vc3RpYyh7XG4gICAgICBjb2RlOiBcIlBBUlNFX0VSUk9SXCIsXG4gICAgICBsYW5ndWFnZTogXCJweXRob25cIixcbiAgICAgIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAgICBtZXNzYWdlOiBgVHJlZS1zaXR0ZXIgZXhwb3NlZCAke25vZGUuaXNNaXNzaW5nID8gXCJhIG1pc3NpbmdcIiA6IFwiYW4gZXJyb3JcIn0gcmVjb3Zlcnkgbm9kZSAnJHtub2RlLnR5cGV9Jy5gXG4gICAgfSlcbiAgfVxuXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBub2RlLmNoaWxkQ291bnQ7IGluZGV4ICs9IDEpIHtcbiAgICBjb25zdCBjaGlsZCA9IG5vZGUuY2hpbGQoaW5kZXgpXG5cbiAgICBpZiAoIWNoaWxkKSB0aHJvdyBuZXcgRXJyb3IoYFRyZWUtc2l0dGVyIG9taXR0ZWQgY2hpbGQgJHtpbmRleH0gb2YgJHtub2RlLnR5cGV9LmApXG4gICAgdmFsaWRhdGVQYXJzZXJUcmVlKGNoaWxkLCBmaWxlbmFtZSwgc291cmNlKVxuICB9XG59XG5cbi8qKlxuICogUmVqZWN0cyBQeXRob24gaWRlbnRpZmllcnMgdGhhdCBjYW5ub3Qgc2FmZWx5IHBhcnRpY2lwYXRlIGluIHRoZSBleGFjdCBwcm9maWxlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gSWRlbnRpZmllciBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IHJvbGUgLSBEaWFnbm9zdGljIHJvbGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge3N0cmluZ30gQWNjZXB0ZWQgbmFtZS5cbiAqL1xuZnVuY3Rpb24gaWRlbnRpZmllcihub2RlLCByb2xlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IG5hbWUgPSBub2RlLnRleHRcblxuICBpZiAobm9kZS50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IHB5dGhvblJlc2VydmVkSWRlbnRpZmllcnMuaGFzKG5hbWUpIHx8IG5hbWUubm9ybWFsaXplKFwiTkZLQ1wiKSAhPSBuYW1lKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIGAke3JvbGV9IGlkZW50aWZpZXIgJyR7bmFtZX0nYCwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG5cbiAgcmV0dXJuIG5hbWVcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgZXhhY3QgaW50L2Jvb2wvc3RyIGFubm90YXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGUgfCBudWxsfSBub2RlIC0gVHlwZSBub2RlLCBpZiBwcmVzZW50LlxuICogQHBhcmFtIHtzdHJpbmd9IHN1YmplY3QgLSBUeXBlZCBzdWJqZWN0LlxuICogQHBhcmFtIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5Tb3VyY2VMb2NhdGlvbn0gb3duZXJMb2NhdGlvbiAtIE93bmluZyBkZWNsYXJhdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuVHlwZVJlZmVyZW5jZX0gU2VtYW50aWMgdHlwZS5cbiAqL1xuZnVuY3Rpb24gY29udmVydFR5cGUobm9kZSwgc3ViamVjdCwgb3duZXJMb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBpZiAoIW5vZGUpIHJldHVybiBtaXNzaW5nVHlwZShcInB5dGhvblwiLCBzdWJqZWN0LCBvd25lckxvY2F0aW9uKVxuICBjb25zdCB0eXBlTG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgY2hpbGRyZW4gPSBub2RlLm5hbWVkQ2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcblxuICBpZiAobm9kZS50eXBlICE9IFwidHlwZVwiIHx8IGNoaWxkcmVuLmxlbmd0aCAhPSAxIHx8IGNoaWxkcmVuWzBdLnR5cGUgIT0gXCJpZGVudGlmaWVyXCIgfHxcbiAgICAhW1wiaW50XCIsIFwiYm9vbFwiLCBcInN0clwiXS5pbmNsdWRlcyhjaGlsZHJlblswXS50ZXh0KSB8fCBub2RlLnRleHQgIT0gY2hpbGRyZW5bMF0udGV4dCkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBcInVuc3VwcG9ydGVkIHNjYWxhciBhbm5vdGF0aW9uXCIsIHR5cGVMb2NhdGlvbilcbiAgfVxuXG4gIHJldHVybiByZXF1aXJlU291cmNlU2NhbGFyVHlwZShcInB5dGhvblwiLCBjaGlsZHJlblswXS50ZXh0LCBzdWJqZWN0LCBvd25lckxvY2F0aW9uLCB0eXBlTG9jYXRpb24pXG59XG5cbi8qKlxuICogRmluZHMgZXhhY3RseSBvbmUgYW5vbnltb3VzIG9wZXJhdG9yIHRva2VuIGRpcmVjdGx5IG93bmVkIGJ5IGEgcGFyc2VyIG5vZGUuXG4gKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBPcGVyYXRpb24gbm9kZS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHNwZWxsaW5ncyAtIEFjY2VwdGVkIHNwZWxsaW5ncy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gT3BlcmF0b3IgdG9rZW4uXG4gKi9cbmZ1bmN0aW9uIG9wZXJhdG9yVG9rZW4obm9kZSwgc3BlbGxpbmdzLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IHRva2VucyA9IG5vZGUuY2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gIWNoaWxkLmlzTmFtZWQgJiYgc3BlbGxpbmdzLmhhcyhjaGlsZC50eXBlKSlcblxuICBpZiAodG9rZW5zLmxlbmd0aCAhPSAxKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgYCR7bm9kZS50eXBlfSBvcGVyYXRvcmAsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcblxuICByZXR1cm4gdG9rZW5zWzBdXG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIHN1cHBvcnRlZCBQeXRob24gZXhwcmVzc2lvbi5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEV4cHJlc3Npb24gbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gU2VtYW50aWMgZXhwcmVzc2lvbi5cbiAqL1xuZnVuY3Rpb24gY29udmVydEV4cHJlc3Npb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICBjb25zdCBsb2NhdGlvbiA9IG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gIGlmIChub2RlLnR5cGUgPT0gXCJwYXJlbnRoZXNpemVkX2V4cHJlc3Npb25cIikge1xuICAgIGNvbnN0IGV4cHJlc3Npb25zID0gbm9kZS5uYW1lZENoaWxkcmVuLmZpbHRlcigoY2hpbGQpID0+IGNoaWxkLnR5cGUgIT0gXCJjb21tZW50XCIpXG5cbiAgICBpZiAoZXhwcmVzc2lvbnMubGVuZ3RoICE9IDEpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBub2RlLnR5cGUsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIGNvbnZlcnRFeHByZXNzaW9uKGV4cHJlc3Npb25zWzBdLCBmaWxlbmFtZSwgc291cmNlKVxuICB9XG4gIGlmIChub2RlLnR5cGUgPT0gXCJpZGVudGlmaWVyXCIpIHtcbiAgICBjb25zdCBuYW1lID0gaWRlbnRpZmllcihub2RlLCBcInJlZmVyZW5jZVwiLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIklkZW50aWZpZXJFeHByZXNzaW9uXCIpLCBsb2NhdGlvbiwgbmFtZX0sIHtuYW1lOiBsb2NhdGlvbn0pXG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcImludGVnZXJcIikge1xuICAgIGxldCB2YWx1ZVxuXG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gTnVtYmVyKEJpZ0ludChub2RlLnRleHQucmVwbGFjZUFsbChcIl9cIiwgXCJcIikpKVxuICAgIH0gY2F0Y2gge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwiaW50ZWdlciBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBpZiAoIU51bWJlci5pc1NhZmVJbnRlZ2VyKHZhbHVlKSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwibm9uLXNhZmUgaW50ZWdlciBsaXRlcmFsXCIsIGxvY2F0aW9uKVxuXG4gICAgcmV0dXJuIHdpdGhQYXJzZXJSYW5nZXMoe2tpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkludGVnZXJMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWV9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG4gIGlmIChub2RlLnR5cGUgPT0gXCJ0cnVlXCIgfHwgbm9kZS50eXBlID09IFwiZmFsc2VcIikge1xuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJCb29sZWFuTGl0ZXJhbFwiKSwgbG9jYXRpb24sIHZhbHVlOiBub2RlLnR5cGUgPT0gXCJ0cnVlXCJ9LCB7bGl0ZXJhbDogbG9jYXRpb259KVxuICB9XG4gIGlmIChub2RlLnR5cGUgPT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJTdHJpbmdMaXRlcmFsXCIpLCBsb2NhdGlvbiwgdmFsdWU6IGRlY29kZVN0cmluZyhub2RlLCBmaWxlbmFtZSwgc291cmNlKX0sIHtcbiAgICAgIGxpdGVyYWw6IGxvY2F0aW9uXG4gICAgfSlcbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiY29uY2F0ZW5hdGVkX3N0cmluZ1wiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJpbXBsaWNpdCBzdHJpbmcgY29uY2F0ZW5hdGlvblwiLCBsb2NhdGlvbilcbiAgaWYgKG5vZGUudHlwZSA9PSBcInVuYXJ5X29wZXJhdG9yXCIpIHtcbiAgICBjb25zdCBvcGVyYW5kTm9kZSA9IHJlcXVpcmVkRmllbGQobm9kZSwgXCJhcmd1bWVudFwiLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IG9wZXJhdG9yID0gb3BlcmF0b3JUb2tlbihub2RlLCBuZXcgU2V0KFtcIi1cIl0pLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IHNlbWFudGljID0gd2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLFxuICAgICAgbG9jYXRpb24sXG4gICAgICBvcGVyYW5kOiBjb252ZXJ0RXhwcmVzc2lvbihvcGVyYW5kTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9LCB7b3BlcmF0b3I6IG5vZGVMb2NhdGlvbihvcGVyYXRvciwgZmlsZW5hbWUsIHNvdXJjZSl9KSwgXCJOZWdhdGVcIilcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChzZW1hbnRpYykpXG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcIm5vdF9vcGVyYXRvclwiKSB7XG4gICAgY29uc3Qgb3BlcmFuZE5vZGUgPSByZXF1aXJlZEZpZWxkKG5vZGUsIFwiYXJndW1lbnRcIiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICBjb25zdCBvcGVyYXRvciA9IG9wZXJhdG9yVG9rZW4obm9kZSwgbmV3IFNldChbXCJub3RcIl0pLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IHNlbWFudGljID0gd2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIlVuYXJ5RXhwcmVzc2lvblwiLFxuICAgICAgbG9jYXRpb24sXG4gICAgICBvcGVyYW5kOiBjb252ZXJ0RXhwcmVzc2lvbihvcGVyYW5kTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9LCB7b3BlcmF0b3I6IG5vZGVMb2NhdGlvbihvcGVyYXRvciwgZmlsZW5hbWUsIHNvdXJjZSl9KSwgXCJOb3RcIilcblxuICAgIHJldHVybiAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkV4cHJlc3Npb259ICovICgvKiogQHR5cGUge3Vua25vd259ICovIChzZW1hbnRpYykpXG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcImJpbmFyeV9vcGVyYXRvclwiIHx8IG5vZGUudHlwZSA9PSBcImNvbXBhcmlzb25fb3BlcmF0b3JcIiB8fCBub2RlLnR5cGUgPT0gXCJib29sZWFuX29wZXJhdG9yXCIpIHtcbiAgICBjb25zdCBleHByZXNzaW9uQ2hpbGRyZW4gPSBub2RlLm5hbWVkQ2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcbiAgICBjb25zdCBsZWZ0Tm9kZSA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoXCJsZWZ0XCIpID8/IGV4cHJlc3Npb25DaGlsZHJlblswXVxuICAgIGNvbnN0IHJpZ2h0Tm9kZSA9IG5vZGUuY2hpbGRGb3JGaWVsZE5hbWUoXCJyaWdodFwiKSA/PyBleHByZXNzaW9uQ2hpbGRyZW5bMV1cblxuICAgIGlmICghbGVmdE5vZGUgfHwgIXJpZ2h0Tm9kZSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbG9jYXRpb24pXG4gICAgY29uc3Qgb3BlcmF0aW9ucyA9IG5vZGUudHlwZSA9PSBcImJpbmFyeV9vcGVyYXRvclwiID8gYmluYXJ5T3BlcmF0aW9ucyA6IG5vZGUudHlwZSA9PSBcImNvbXBhcmlzb25fb3BlcmF0b3JcIlxuICAgICAgPyBjb21wYXJpc29uT3BlcmF0aW9ucyA6IG5ldyBNYXAoW1tcImFuZFwiLCBcIkFuZFwiXSwgW1wib3JcIiwgXCJPclwiXV0pXG4gICAgY29uc3Qgb3BlcmF0b3IgPSBvcGVyYXRvclRva2VuKG5vZGUsIG5ldyBTZXQob3BlcmF0aW9ucy5rZXlzKCkpLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IGFkYXB0ZWQgPSBvcGVyYXRpb25zLmdldChvcGVyYXRvci50eXBlKVxuXG4gICAgaWYgKCFhZGFwdGVkIHx8IGV4cHJlc3Npb25DaGlsZHJlbi5sZW5ndGggIT0gMikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHNlbWFudGljID0gd2l0aEFkYXB0ZWRPcGVyYXRpb24od2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiBcIkJpbmFyeUV4cHJlc3Npb25cIixcbiAgICAgIGxlZnQ6IGNvbnZlcnRFeHByZXNzaW9uKGxlZnROb2RlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgcmlnaHQ6IGNvbnZlcnRFeHByZXNzaW9uKHJpZ2h0Tm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9LCB7b3BlcmF0b3I6IG5vZGVMb2NhdGlvbihvcGVyYXRvciwgZmlsZW5hbWUsIHNvdXJjZSl9KSwgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy9vcGVyYXRvcnMuanNcIikuQWRhcHRlZE9wZXJhdGlvbn0gKi8gKGFkYXB0ZWQpKVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRXhwcmVzc2lvbn0gKi8gKC8qKiBAdHlwZSB7dW5rbm93bn0gKi8gKHNlbWFudGljKSlcbiAgfVxuICBpZiAobm9kZS50eXBlID09IFwiY2FsbFwiKSB7XG4gICAgY29uc3QgY2FsbGVlTm9kZSA9IHJlcXVpcmVkRmllbGQobm9kZSwgXCJmdW5jdGlvblwiLCBmaWxlbmFtZSwgc291cmNlKVxuICAgIGNvbnN0IGFyZ3VtZW50c05vZGUgPSByZXF1aXJlZEZpZWxkKG5vZGUsIFwiYXJndW1lbnRzXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICBpZiAoY2FsbGVlTm9kZS50eXBlICE9IFwiaWRlbnRpZmllclwiIHx8IGFyZ3VtZW50c05vZGUudHlwZSAhPSBcImFyZ3VtZW50X2xpc3RcIikge1xuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwiZHluYW1pYyBjYWxsXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBjb25zdCBjYWxsZWUgPSBpZGVudGlmaWVyKGNhbGxlZU5vZGUsIFwiY2FsbGVlXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgY29uc3QgYXJndW1lbnRzXyA9IGFyZ3VtZW50c05vZGUubmFtZWRDaGlsZHJlbi5maWx0ZXIoKGNoaWxkKSA9PiBjaGlsZC50eXBlICE9IFwiY29tbWVudFwiKVxuICAgICAgLm1hcCgoYXJndW1lbnQpID0+IGNvbnZlcnRFeHByZXNzaW9uKGFyZ3VtZW50LCBmaWxlbmFtZSwgc291cmNlKSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHthcmd1bWVudHM6IGFyZ3VtZW50c18sIGNhbGxlZSwga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQ2FsbEV4cHJlc3Npb25cIiksIGxvY2F0aW9ufSwge1xuICAgICAgY2FsbGVlOiBub2RlTG9jYXRpb24oY2FsbGVlTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgICB9KVxuICB9XG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogRGVjb2RlcyBvbmUgbm9uLXByZWZpeGVkLCBub24tdHJpcGxlIFB5dGhvbiBzdHJpbmcgd2l0aG91dCBldmFsdWF0aW5nIHNvdXJjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIFN0cmluZyBub2RlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFVuaWNvZGUgc2NhbGFyIHN0cmluZy5cbiAqL1xuZnVuY3Rpb24gZGVjb2RlU3RyaW5nKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgdGV4dCA9IG5vZGUudGV4dFxuICBjb25zdCBxdW90ZSA9IHRleHRbMF1cblxuICBpZiAoKHF1b3RlICE9IFwiXFxcIlwiICYmIHF1b3RlICE9IFwiJ1wiKSB8fCB0ZXh0LmF0KC0xKSAhPSBxdW90ZSB8fCB0ZXh0LnN0YXJ0c1dpdGgoYCR7cXVvdGV9JHtxdW90ZX0ke3F1b3RlfWApKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwicHJlZml4ZWQgb3IgdHJpcGxlLXF1b3RlZCBzdHJpbmdcIiwgbG9jYXRpb24pXG4gIH1cbiAgbGV0IGRlY29kZWQgPSBcIlwiXG5cbiAgZm9yIChsZXQgaW5kZXggPSAxOyBpbmRleCA8IHRleHQubGVuZ3RoIC0gMTsgaW5kZXggKz0gMSkge1xuICAgIGNvbnN0IGNoYXJhY3RlciA9IHRleHRbaW5kZXhdXG5cbiAgICBpZiAoY2hhcmFjdGVyICE9IFwiXFxcXFwiKSB7XG4gICAgICBkZWNvZGVkICs9IGNoYXJhY3RlclxuICAgICAgY29udGludWVcbiAgICB9XG4gICAgY29uc3QgZXNjYXBlID0gdGV4dFsrK2luZGV4XVxuXG4gICAgaWYgKGVzY2FwZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJpbnZhbGlkIHN0cmluZyBlc2NhcGVcIiwgbG9jYXRpb24pXG4gICAgY29uc3Qgc2ltcGxlID0gbmV3IE1hcChbXG4gICAgICBbXCJcXFxcXCIsIFwiXFxcXFwiXSwgW1wiJ1wiLCBcIidcIl0sIFtcIlxcXCJcIiwgXCJcXFwiXCJdLCBbXCJhXCIsIFwiXFx1MDAwN1wiXSwgW1wiYlwiLCBcIlxcYlwiXSwgW1wiZlwiLCBcIlxcZlwiXSwgW1wiblwiLCBcIlxcblwiXSxcbiAgICAgIFtcInJcIiwgXCJcXHJcIl0sIFtcInRcIiwgXCJcXHRcIl0sIFtcInZcIiwgXCJcXHZcIl1cbiAgICBdKVxuXG4gICAgaWYgKHNpbXBsZS5oYXMoZXNjYXBlKSkge1xuICAgICAgZGVjb2RlZCArPSBzaW1wbGUuZ2V0KGVzY2FwZSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGlmICgvWzAtN10vdS50ZXN0KGVzY2FwZSkpIHtcbiAgICAgIGxldCBkaWdpdHMgPSBlc2NhcGVcblxuICAgICAgd2hpbGUgKGRpZ2l0cy5sZW5ndGggPCAzICYmIC9bMC03XS91LnRlc3QodGV4dFtpbmRleCArIDFdID8/IFwiXCIpKSBkaWdpdHMgKz0gdGV4dFsrK2luZGV4XVxuICAgICAgZGVjb2RlZCArPSBTdHJpbmcuZnJvbUNvZGVQb2ludChOdW1iZXIucGFyc2VJbnQoZGlnaXRzLCA4KSlcbiAgICAgIGNvbnRpbnVlXG4gICAgfVxuICAgIGNvbnN0IHdpZHRocyA9IG5ldyBNYXAoW1tcInhcIiwgMl0sIFtcInVcIiwgNF0sIFtcIlVcIiwgOF1dKVxuICAgIGNvbnN0IHdpZHRoID0gd2lkdGhzLmdldChlc2NhcGUpXG5cbiAgICBpZiAoIXdpZHRoKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgYHVuc3VwcG9ydGVkIHN0cmluZyBlc2NhcGUgXFxcXCR7ZXNjYXBlfWAsIGxvY2F0aW9uKVxuICAgIGNvbnN0IGRpZ2l0cyA9IHRleHQuc2xpY2UoaW5kZXggKyAxLCBpbmRleCArIDEgKyB3aWR0aClcbiAgICBpZiAoZGlnaXRzLmxlbmd0aCAhPSB3aWR0aCB8fCAhL15bMC05QS1GYS1mXSskL3UudGVzdChkaWdpdHMpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJpbnZhbGlkIHN0cmluZyBlc2NhcGVcIiwgbG9jYXRpb24pXG4gICAgaW5kZXggKz0gd2lkdGhcbiAgICBjb25zdCBjb2RlUG9pbnQgPSBOdW1iZXIucGFyc2VJbnQoZGlnaXRzLCAxNilcblxuICAgIGlmIChjb2RlUG9pbnQgPiAweDEwRkZGRiB8fCBjb2RlUG9pbnQgPj0gMHhEODAwICYmIGNvZGVQb2ludCA8PSAweERGRkYpIHtcbiAgICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBcImludmFsaWQgVW5pY29kZSBzdHJpbmcgZXNjYXBlXCIsIGxvY2F0aW9uKVxuICAgIH1cbiAgICBkZWNvZGVkICs9IFN0cmluZy5mcm9tQ29kZVBvaW50KGNvZGVQb2ludClcbiAgfVxuXG4gIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKGRlY29kZWQpKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJpbnZhbGlkIFVuaWNvZGUgc3RyaW5nIGxpdGVyYWxcIiwgbG9jYXRpb24pXG5cbiAgcmV0dXJuIGRlY29kZWRcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBvbmUgYW5ub3RhdGVkIGFzc2lnbm1lbnQgb3IgcGxhaW4gYXNzaWdubWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEFzc2lnbm1lbnQgbm9kZS5cbiAqIEBwYXJhbSB7UHl0aG9uQ29udGV4dH0gY29udGV4dCAtIENvbW1lbnQgYXNzb2NpYXRpb24gc3RhdGUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB2aXNpYmxlIC0gVmlzaWJsZSBiaW5kaW5ncyBpbiB0aGlzIGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkxvY2FsU3RhdGVtZW50fSBTZW1hbnRpYyBsb2NhbCBzdGF0ZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRBc3NpZ25tZW50KG5vZGUsIGNvbnRleHQsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgbGVmdCA9IHJlcXVpcmVkRmllbGQobm9kZSwgXCJsZWZ0XCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IHJpZ2h0ID0gcmVxdWlyZWRGaWVsZChub2RlLCBcInJpZ2h0XCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IHR5cGVOb2RlID0gbm9kZS5jaGlsZEZvckZpZWxkTmFtZShcInR5cGVcIilcblxuICBpZiAobGVmdC50eXBlICE9IFwiaWRlbnRpZmllclwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJub24taWRlbnRpZmllciBhc3NpZ25tZW50IHRhcmdldFwiLCBub2RlTG9jYXRpb24obGVmdCwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIGNvbnN0IG5hbWUgPSBpZGVudGlmaWVyKGxlZnQsIHR5cGVOb2RlID8gXCJsb2NhbFwiIDogXCJhc3NpZ25tZW50IHRhcmdldFwiLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBuYW1lTG9jYXRpb24gPSBub2RlTG9jYXRpb24obGVmdCwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3Qgb3BlcmF0b3IgPSBvcGVyYXRvclRva2VuKG5vZGUsIG5ldyBTZXQoW1wiPVwiXSksIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKCF0eXBlTm9kZSkge1xuICAgIGlmICghdmlzaWJsZS5oYXMobmFtZSkpIHJldHVybiBtaXNzaW5nVHlwZShcInB5dGhvblwiLCBgTG9jYWwgJyR7bmFtZX0nYCwgbG9jYXRpb24pXG4gICAgY29uc3QgdGFyZ2V0ID0gd2l0aFBhcnNlclJhbmdlcyh7a2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiSWRlbnRpZmllckV4cHJlc3Npb25cIiksIGxvY2F0aW9uOiBuYW1lTG9jYXRpb24sIG5hbWV9LCB7bmFtZTogbmFtZUxvY2F0aW9ufSlcblxuICAgIHJldHVybiB3aXRoUGFyc2VyUmFuZ2VzKHtcbiAgICAgIGV4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKHJpZ2h0LCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICAgIGtpbmQ6IC8qKiBAdHlwZSB7Y29uc3R9ICovIChcIkFzc2lnbm1lbnRTdGF0ZW1lbnRcIiksXG4gICAgICBsb2NhdGlvbixcbiAgICAgIHRhcmdldFxuICAgIH0sIHtvcGVyYXRvcjogbm9kZUxvY2F0aW9uKG9wZXJhdG9yLCBmaWxlbmFtZSwgc291cmNlKX0pXG4gIH1cblxuICBjb25zdCBkZWNsYXJhdGlvbiA9IHdpdGhQYXJzZXJSYW5nZXMoe1xuICAgIGluaXRpYWxpemVyOiBjb252ZXJ0RXhwcmVzc2lvbihyaWdodCwgZmlsZW5hbWUsIHNvdXJjZSksXG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiTG9jYWxEZWNsYXJhdGlvblwiKSxcbiAgICBsb2NhdGlvbixcbiAgICBtdXRhYmxlOiAhdGFrZUltbXV0YWJsZU1hcmtlcihub2RlLCBjb250ZXh0KSxcbiAgICBuYW1lLFxuICAgIHR5cGU6IGNvbnZlcnRUeXBlKHR5cGVOb2RlLCBgTG9jYWwgJyR7bmFtZX0nYCwgbG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpXG4gIH0sIHtuYW1lOiBuYW1lTG9jYXRpb24sIG9wZXJhdG9yOiBub2RlTG9jYXRpb24ob3BlcmF0b3IsIGZpbGVuYW1lLCBzb3VyY2UpfSlcblxuICB2aXNpYmxlLmFkZChuYW1lKVxuXG4gIHJldHVybiBkZWNsYXJhdGlvblxufVxuXG4vKipcbiAqIEFzc29jaWF0ZXMgdGhlIGV4YWN0IGltbWVkaWF0ZWx5IHByZWNlZGluZyBpbW11dGFibGUgbWFya2VyIHdpdGggYSBsb2NhbC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIExvY2FsIGFzc2lnbm1lbnQuXG4gKiBAcGFyYW0ge1B5dGhvbkNvbnRleHR9IGNvbnRleHQgLSBDb21tZW50IHN0YXRlLlxuICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgdGhlIGxvY2FsIGlzIGltbXV0YWJsZS5cbiAqL1xuZnVuY3Rpb24gdGFrZUltbXV0YWJsZU1hcmtlcihub2RlLCBjb250ZXh0KSB7XG4gIGNvbnN0IG1hcmtlciA9IGNvbnRleHQuY29tbWVudHMuZmluZCgoY29tbWVudCkgPT4gY29tbWVudC50ZXh0ID09IGltbXV0YWJsZU1hcmtlciAmJlxuICAgIGNvbW1lbnQuZW5kUG9zaXRpb24ucm93ICsgMSA9PSBub2RlLnN0YXJ0UG9zaXRpb24ucm93ICYmIGNvbW1lbnQuc3RhcnRQb3NpdGlvbi5jb2x1bW4gPT0gbm9kZS5zdGFydFBvc2l0aW9uLmNvbHVtbilcblxuICBpZiAoIW1hcmtlcikgcmV0dXJuIGZhbHNlXG4gIGNvbnRleHQudXNlZEltbXV0YWJsZU1hcmtlcnMuYWRkKG1hcmtlcilcblxuICByZXR1cm4gdHJ1ZVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBzdGF0ZW1lbnQuXG4gKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBTdGF0ZW1lbnQgbm9kZS5cbiAqIEBwYXJhbSB7UHl0aG9uQ29udGV4dH0gY29udGV4dCAtIENvbW1lbnQgc3RhdGUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB2aXNpYmxlIC0gVmlzaWJsZSBiaW5kaW5ncyBpbiB0aGlzIGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlN0YXRlbWVudH0gU2VtYW50aWMgc3RhdGVtZW50LlxuICovXG5mdW5jdGlvbiBjb252ZXJ0U3RhdGVtZW50KG5vZGUsIGNvbnRleHQsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS50eXBlID09IFwicmV0dXJuX3N0YXRlbWVudFwiKSB7XG4gICAgY29uc3QgZXhwcmVzc2lvbnMgPSBub2RlLm5hbWVkQ2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcblxuICAgIGlmIChleHByZXNzaW9ucy5sZW5ndGggIT0gMSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwicmV0dXJuIHdpdGhvdXQgb25lIGV4cHJlc3Npb25cIiwgbG9jYXRpb24pXG5cbiAgICByZXR1cm4ge2V4cHJlc3Npb246IGNvbnZlcnRFeHByZXNzaW9uKGV4cHJlc3Npb25zWzBdLCBmaWxlbmFtZSwgc291cmNlKSwga2luZDogXCJSZXR1cm5TdGF0ZW1lbnRcIiwgbG9jYXRpb259XG4gIH1cbiAgaWYgKG5vZGUudHlwZSA9PSBcImlmX3N0YXRlbWVudFwiKSByZXR1cm4gY29udmVydElmKG5vZGUsIGNvbnRleHQsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGlmIChub2RlLnR5cGUgPT0gXCJleHByZXNzaW9uX3N0YXRlbWVudFwiKSB7XG4gICAgY29uc3QgZXhwcmVzc2lvbnMgPSBub2RlLm5hbWVkQ2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcblxuICAgIGlmIChleHByZXNzaW9ucy5sZW5ndGggIT0gMSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbG9jYXRpb24pXG4gICAgaWYgKGV4cHJlc3Npb25zWzBdLnR5cGUgPT0gXCJhc3NpZ25tZW50XCIpIHJldHVybiBjb252ZXJ0QXNzaWdubWVudChleHByZXNzaW9uc1swXSwgY29udGV4dCwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIHJldHVybiBjb252ZXJ0UHJpbnQoZXhwcmVzc2lvbnNbMF0sIGZpbGVuYW1lLCBzb3VyY2UsIGxvY2F0aW9uKVxuICB9XG5cbiAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbG9jYXRpb24pXG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGV4YWN0IHByaW50KGV4cHJlc3Npb24pIHN0YXRlbWVudC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIEV4cHJlc3Npb24gc3RhdGVtZW50IHZhbHVlLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gU291cmNlIGZpbGVuYW1lLlxuICogQHBhcmFtIHtzdHJpbmd9IHNvdXJjZSAtIENvbXBsZXRlIHNvdXJjZS5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuU291cmNlTG9jYXRpb259IGxvY2F0aW9uIC0gV2hvbGUgc3RhdGVtZW50IGxvY2F0aW9uLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLlByaW50U3RhdGVtZW50fSBQcmludCBzdGF0ZW1lbnQuXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRQcmludChub2RlLCBmaWxlbmFtZSwgc291cmNlLCBsb2NhdGlvbikge1xuICBpZiAobm9kZS50eXBlICE9IFwiY2FsbFwiKSByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJlbnRyeSBleHByZXNzaW9uIG90aGVyIHRoYW4gcHJpbnRcIiwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICBjb25zdCBjYWxsZWUgPSByZXF1aXJlZEZpZWxkKG5vZGUsIFwiZnVuY3Rpb25cIiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgYXJndW1lbnRzTm9kZSA9IHJlcXVpcmVkRmllbGQobm9kZSwgXCJhcmd1bWVudHNcIiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgYXJndW1lbnRzXyA9IGFyZ3VtZW50c05vZGUubmFtZWRDaGlsZHJlbi5maWx0ZXIoKGNoaWxkKSA9PiBjaGlsZC50eXBlICE9IFwiY29tbWVudFwiKVxuXG4gIGlmIChjYWxsZWUudHlwZSAhPSBcImlkZW50aWZpZXJcIiB8fCBjYWxsZWUudGV4dCAhPSBcInByaW50XCIgfHwgYXJndW1lbnRzTm9kZS50eXBlICE9IFwiYXJndW1lbnRfbGlzdFwiIHx8IGFyZ3VtZW50c18ubGVuZ3RoICE9IDEpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgXCJwcmludCBjYWxsIHNoYXBlXCIsIG5vZGVMb2NhdGlvbihub2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuXG4gIHJldHVybiB7ZXhwcmVzc2lvbjogY29udmVydEV4cHJlc3Npb24oYXJndW1lbnRzX1swXSwgZmlsZW5hbWUsIHNvdXJjZSksIGtpbmQ6IFwiUHJpbnRTdGF0ZW1lbnRcIiwgbG9jYXRpb259XG59XG5cbi8qKlxuICogQ29udmVydHMgb25lIGlmL2VsaWYvZWxzZSBub2RlIGludG8gbmVzdGVkIHNlbWFudGljIGJsb2Nrcy5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZX0gbm9kZSAtIElmIG9yIGVsaWYgbm9kZS5cbiAqIEBwYXJhbSB7UHl0aG9uQ29udGV4dH0gY29udGV4dCAtIENvbW1lbnQgc3RhdGUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB2aXNpYmxlIC0gVmlzaWJsZSBiaW5kaW5ncyBpbiB0aGlzIGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLklmU3RhdGVtZW50fSBTZW1hbnRpYyBicmFuY2guXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRJZihub2RlLCBjb250ZXh0LCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGNvbmRpdGlvbk5vZGUgPSByZXF1aXJlZEZpZWxkKG5vZGUsIFwiY29uZGl0aW9uXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IGNvbnNlcXVlbmNlTm9kZSA9IHJlcXVpcmVkRmllbGQobm9kZSwgXCJjb25zZXF1ZW5jZVwiLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBhbHRlcm5hdGl2ZU5vZGVzID0gbm9kZS5uYW1lZENoaWxkcmVuLmZpbHRlcigoX2NoaWxkLCBpbmRleCkgPT4gbm9kZS5maWVsZE5hbWVGb3JOYW1lZENoaWxkKGluZGV4KSA9PSBcImFsdGVybmF0aXZlXCIpXG4gIGNvbnN0IGFsdGVybmF0ZSA9IGNvbnZlcnRBbHRlcm5hdGl2ZXMoYWx0ZXJuYXRpdmVOb2RlcywgY29udGV4dCwgbmV3IFNldCh2aXNpYmxlKSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICByZXR1cm4ge1xuICAgIC4uLihhbHRlcm5hdGUgPyB7YWx0ZXJuYXRlfSA6IHt9KSxcbiAgICBjb25kaXRpb246IGNvbnZlcnRFeHByZXNzaW9uKGNvbmRpdGlvbk5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIGNvbnNlcXVlbnQ6IGNvbnZlcnRCbG9jayhjb25zZXF1ZW5jZU5vZGUsIGNvbnRleHQsIG5ldyBTZXQodmlzaWJsZSksIGZpbGVuYW1lLCBzb3VyY2UpLFxuICAgIGtpbmQ6IFwiSWZTdGF0ZW1lbnRcIixcbiAgICBsb2NhdGlvblxuICB9XG59XG5cbi8qKlxuICogQ29udmVydHMgYW4gZWxzZSBibG9jayBvciBuZXN0cyBvbmUgZWxpZiBpbnNpZGUgaXRzIHNlbWFudGljIGFsdGVybmF0ZSBibG9jay5cbiAqIEBwYXJhbSB7aW1wb3J0KFwidHJlZS1zaXR0ZXJcIikuU3ludGF4Tm9kZVtdfSBub2RlcyAtIE9yZGVyZWQgZWxpZi9lbHNlIG5vZGVzLlxuICogQHBhcmFtIHtQeXRob25Db250ZXh0fSBjb250ZXh0IC0gQ29tbWVudCBzdGF0ZS5cbiAqIEBwYXJhbSB7U2V0PHN0cmluZz59IHZpc2libGUgLSBWaXNpYmxlIGJpbmRpbmdzIGluIHRoaXMgbGV4aWNhbCBzY29wZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuQmxvY2sgfCB1bmRlZmluZWR9IEFsdGVybmF0ZSBibG9jay5cbiAqL1xuZnVuY3Rpb24gY29udmVydEFsdGVybmF0aXZlcyhub2RlcywgY29udGV4dCwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSkge1xuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrIHwgdW5kZWZpbmVkfSAqL1xuICBsZXQgYWx0ZXJuYXRlXG5cbiAgZm9yIChsZXQgaW5kZXggPSBub2Rlcy5sZW5ndGggLSAxOyBpbmRleCA+PSAwOyBpbmRleCAtPSAxKSB7XG4gICAgY29uc3Qgbm9kZSA9IG5vZGVzW2luZGV4XVxuXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImVsc2VfY2xhdXNlXCIpIHtcbiAgICAgIGlmIChhbHRlcm5hdGUpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBcIm11bHRpcGxlIGVsc2UgY2xhdXNlc1wiLCBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gICAgICBhbHRlcm5hdGUgPSBjb252ZXJ0QmxvY2socmVxdWlyZWRGaWVsZChub2RlLCBcImJvZHlcIiwgZmlsZW5hbWUsIHNvdXJjZSksIGNvbnRleHQsIG5ldyBTZXQodmlzaWJsZSksIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgICBjb250aW51ZVxuICAgIH1cbiAgICBpZiAobm9kZS50eXBlICE9IFwiZWxpZl9jbGF1c2VcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICAgIGNvbnN0IG5lc3RlZCA9IGNvbnZlcnRJZihub2RlLCBjb250ZXh0LCBuZXcgU2V0KHZpc2libGUpLCBmaWxlbmFtZSwgc291cmNlKVxuXG4gICAgaWYgKGFsdGVybmF0ZSkgbmVzdGVkLmFsdGVybmF0ZSA9IGFsdGVybmF0ZVxuICAgIGFsdGVybmF0ZSA9IHtraW5kOiBcIkJsb2NrXCIsIGxvY2F0aW9uOiBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSksIHN0YXRlbWVudHM6IFtuZXN0ZWRdfVxuICB9XG5cbiAgcmV0dXJuIGFsdGVybmF0ZVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBpbmRlbnRhdGlvbiBibG9jayBhbmQgcGVybWl0cyBwYXNzIG9ubHkgYXMgaXRzIHNvbGUgZXhlY3V0YWJsZSBub2RlLlxuICogQHBhcmFtIHtpbXBvcnQoXCJ0cmVlLXNpdHRlclwiKS5TeW50YXhOb2RlfSBub2RlIC0gQmxvY2sgbm9kZS5cbiAqIEBwYXJhbSB7UHl0aG9uQ29udGV4dH0gY29udGV4dCAtIENvbW1lbnQgc3RhdGUuXG4gKiBAcGFyYW0ge1NldDxzdHJpbmc+fSB2aXNpYmxlIC0gVmlzaWJsZSBiaW5kaW5ncyBpbiB0aGlzIGxleGljYWwgc2NvcGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gZmlsZW5hbWUgLSBTb3VyY2UgZmlsZW5hbWUuXG4gKiBAcGFyYW0ge3N0cmluZ30gc291cmNlIC0gQ29tcGxldGUgc291cmNlLlxuICogQHJldHVybnMge2ltcG9ydChcIi4uL3NlbWFudGljL3R5cGVzLmpzXCIpLkJsb2NrfSBTZW1hbnRpYyBibG9jay5cbiAqL1xuZnVuY3Rpb24gY29udmVydEJsb2NrKG5vZGUsIGNvbnRleHQsIHZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpIHtcbiAgY29uc3QgbG9jYXRpb24gPSBub2RlTG9jYXRpb24obm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICBpZiAobm9kZS50eXBlICE9IFwiYmxvY2tcIikgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIG5vZGUudHlwZSwgbG9jYXRpb24pXG4gIGNvbnN0IHN0YXRlbWVudHMgPSBub2RlLm5hbWVkQ2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcblxuICBpZiAoc3RhdGVtZW50cy5zb21lKChzdGF0ZW1lbnQpID0+IHN0YXRlbWVudC50eXBlID09IFwicGFzc19zdGF0ZW1lbnRcIikpIHtcbiAgICBpZiAoc3RhdGVtZW50cy5sZW5ndGggIT0gMSkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwicGFzcyB3aXRoIGV4ZWN1dGFibGUgc2libGluZ3NcIiwgbG9jYXRpb24pXG5cbiAgICByZXR1cm4ge2tpbmQ6IFwiQmxvY2tcIiwgbG9jYXRpb24sIHN0YXRlbWVudHM6IFtdfVxuICB9XG5cbiAgcmV0dXJuIHtraW5kOiBcIkJsb2NrXCIsIGxvY2F0aW9uLCBzdGF0ZW1lbnRzOiBzdGF0ZW1lbnRzLm1hcCgoc3RhdGVtZW50KSA9PiBjb252ZXJ0U3RhdGVtZW50KHN0YXRlbWVudCwgY29udGV4dCwgdmlzaWJsZSwgZmlsZW5hbWUsIHNvdXJjZSkpfVxufVxuXG4vKipcbiAqIENvbnZlcnRzIG9uZSBleGFjdCBzeW5jaHJvbm91cyB0b3AtbGV2ZWwgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcInRyZWUtc2l0dGVyXCIpLlN5bnRheE5vZGV9IG5vZGUgLSBGdW5jdGlvbiBub2RlLlxuICogQHBhcmFtIHtQeXRob25Db250ZXh0fSBjb250ZXh0IC0gQ29tbWVudCBzdGF0ZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBmaWxlbmFtZSAtIFNvdXJjZSBmaWxlbmFtZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBzb3VyY2UgLSBDb21wbGV0ZSBzb3VyY2UuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vc2VtYW50aWMvdHlwZXMuanNcIikuRnVuY3Rpb25EZWNsYXJhdGlvbn0gU2VtYW50aWMgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNvbnZlcnRGdW5jdGlvbihub2RlLCBjb250ZXh0LCBmaWxlbmFtZSwgc291cmNlKSB7XG4gIGNvbnN0IGxvY2F0aW9uID0gbm9kZUxvY2F0aW9uKG5vZGUsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgaWYgKG5vZGUudHlwZSAhPSBcImZ1bmN0aW9uX2RlZmluaXRpb25cIiB8fCBub2RlLmNoaWxkcmVuLnNvbWUoKGNoaWxkKSA9PiAhY2hpbGQuaXNOYW1lZCAmJiBjaGlsZC50eXBlID09IFwiYXN5bmNcIikpIHtcbiAgICByZXR1cm4gdW5zdXBwb3J0ZWRTeW50YXgoXCJweXRob25cIiwgbm9kZS50eXBlLCBsb2NhdGlvbilcbiAgfVxuICBjb25zdCB0eXBlUGFyYW1ldGVyc05vZGUgPSBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwidHlwZV9wYXJhbWV0ZXJzXCIpXG5cbiAgaWYgKHR5cGVQYXJhbWV0ZXJzTm9kZSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCB0eXBlUGFyYW1ldGVyc05vZGUudHlwZSwgbm9kZUxvY2F0aW9uKHR5cGVQYXJhbWV0ZXJzTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSkpXG4gIH1cbiAgY29uc3QgbmFtZU5vZGUgPSByZXF1aXJlZEZpZWxkKG5vZGUsIFwibmFtZVwiLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBwYXJhbWV0ZXJzTm9kZSA9IHJlcXVpcmVkRmllbGQobm9kZSwgXCJwYXJhbWV0ZXJzXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGNvbnN0IHJldHVybk5vZGUgPSBub2RlLmNoaWxkRm9yRmllbGROYW1lKFwicmV0dXJuX3R5cGVcIilcbiAgY29uc3QgYm9keU5vZGUgPSByZXF1aXJlZEZpZWxkKG5vZGUsIFwiYm9keVwiLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBuYW1lID0gaWRlbnRpZmllcihuYW1lTm9kZSwgXCJmdW5jdGlvblwiLCBmaWxlbmFtZSwgc291cmNlKVxuICBjb25zdCBwYXJhbWV0ZXJOb2RlcyA9IHBhcmFtZXRlcnNOb2RlLm5hbWVkQ2hpbGRyZW4uZmlsdGVyKChjaGlsZCkgPT4gY2hpbGQudHlwZSAhPSBcImNvbW1lbnRcIilcblxuICBpZiAocGFyYW1ldGVyc05vZGUuY2hpbGRyZW4uc29tZSgoY2hpbGQpID0+ICFjaGlsZC5pc05hbWVkICYmICFbXCIoXCIsIFwiKVwiLCBcIixcIl0uaW5jbHVkZXMoY2hpbGQudHlwZSkpKSB7XG4gICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwicGFyYW1ldGVyIHNlcGFyYXRvcnNcIiwgbm9kZUxvY2F0aW9uKHBhcmFtZXRlcnNOb2RlLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgfVxuICBjb25zdCBwYXJhbWV0ZXJzID0gcGFyYW1ldGVyTm9kZXMubWFwKChwYXJhbWV0ZXJOb2RlKSA9PiB7XG4gICAgY29uc3QgcGFyYW1ldGVyTG9jYXRpb24gPSBub2RlTG9jYXRpb24ocGFyYW1ldGVyTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSlcblxuICAgIGlmIChwYXJhbWV0ZXJOb2RlLnR5cGUgIT0gXCJ0eXBlZF9wYXJhbWV0ZXJcIikge1xuICAgICAgaWYgKHBhcmFtZXRlck5vZGUudHlwZSA9PSBcImlkZW50aWZpZXJcIikgcmV0dXJuIG1pc3NpbmdUeXBlKFwicHl0aG9uXCIsIGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTm9kZS50ZXh0fSdgLCBwYXJhbWV0ZXJMb2NhdGlvbilcblxuICAgICAgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIHBhcmFtZXRlck5vZGUudHlwZSwgcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgfVxuICAgIGNvbnN0IHBhcmFtZXRlck5hbWVOb2RlID0gcGFyYW1ldGVyTm9kZS5uYW1lZENoaWxkcmVuLmZpbmQoKGNoaWxkKSA9PiBjaGlsZC50eXBlID09IFwiaWRlbnRpZmllclwiKVxuICAgIGNvbnN0IHR5cGVOb2RlID0gcGFyYW1ldGVyTm9kZS5jaGlsZEZvckZpZWxkTmFtZShcInR5cGVcIilcblxuICAgIGlmICghcGFyYW1ldGVyTmFtZU5vZGUpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBcInBhcmFtZXRlciB3aXRob3V0IGlkZW50aWZpZXJcIiwgcGFyYW1ldGVyTG9jYXRpb24pXG4gICAgY29uc3QgcGFyYW1ldGVyTmFtZSA9IGlkZW50aWZpZXIocGFyYW1ldGVyTmFtZU5vZGUsIFwicGFyYW1ldGVyXCIsIGZpbGVuYW1lLCBzb3VyY2UpXG5cbiAgICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgICBraW5kOiAvKiogQHR5cGUge2NvbnN0fSAqLyAoXCJQYXJhbWV0ZXJcIiksXG4gICAgICBsb2NhdGlvbjogcGFyYW1ldGVyTG9jYXRpb24sXG4gICAgICBuYW1lOiBwYXJhbWV0ZXJOYW1lLFxuICAgICAgdHlwZTogY29udmVydFR5cGUodHlwZU5vZGUsIGBQYXJhbWV0ZXIgJyR7cGFyYW1ldGVyTmFtZX0nYCwgcGFyYW1ldGVyTG9jYXRpb24sIGZpbGVuYW1lLCBzb3VyY2UpXG4gICAgfSwge25hbWU6IG5vZGVMb2NhdGlvbihwYXJhbWV0ZXJOYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxuICB9KVxuXG4gIGNvbnN0IHZpc2libGUgPSBuZXcgU2V0KHBhcmFtZXRlcnMubWFwKChwYXJhbWV0ZXIpID0+IHBhcmFtZXRlci5uYW1lKSlcblxuICByZXR1cm4gd2l0aFBhcnNlclJhbmdlcyh7XG4gICAgYm9keTogY29udmVydEJsb2NrKGJvZHlOb2RlLCBjb250ZXh0LCB2aXNpYmxlLCBmaWxlbmFtZSwgc291cmNlKSxcbiAgICBraW5kOiBcIkZ1bmN0aW9uRGVjbGFyYXRpb25cIixcbiAgICBsb2NhdGlvbixcbiAgICBuYW1lLFxuICAgIHBhcmFtZXRlcnMsXG4gICAgcmV0dXJuVHlwZTogY29udmVydFR5cGUocmV0dXJuTm9kZSwgYEZ1bmN0aW9uICcke25hbWV9JyByZXR1cm5gLCBsb2NhdGlvbiwgZmlsZW5hbWUsIHNvdXJjZSlcbiAgfSwge25hbWU6IG5vZGVMb2NhdGlvbihuYW1lTm9kZSwgZmlsZW5hbWUsIHNvdXJjZSl9KVxufVxuXG4vKipcbiAqIFBhcnNlcyB0aGUgc3RyaWN0IFRhc2sgMDE2IFB5dGhvbiBwcm9maWxlLlxuICogQHBhcmFtIHt7ZmlsZW5hbWU6IHN0cmluZywgc291cmNlOiBzdHJpbmd9fSBpbnB1dCAtIFBhcnNlciBpbnB1dC5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9zZW1hbnRpYy90eXBlcy5qc1wiKS5TZW1hbnRpY01vZHVsZX0gU2VtYW50aWMgbW9kdWxlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VQeXRob24oe2ZpbGVuYW1lLCBzb3VyY2V9KSB7XG4gIGlmICghaGFzT25seVVuaWNvZGVTY2FsYXJzKHNvdXJjZSkpIHtcbiAgICBjb25zdCBpbnZhbGlkT2Zmc2V0ID0gZmlyc3RMb25lU3Vycm9nYXRlT2Zmc2V0KHNvdXJjZSlcblxuICAgIHRocm93IG5ldyBTZW1hbnRpZm9sZERpYWdub3N0aWMoe1xuICAgICAgY29kZTogXCJQQVJTRV9FUlJPUlwiLFxuICAgICAgbGFuZ3VhZ2U6IFwicHl0aG9uXCIsXG4gICAgICBsb2NhdGlvbjogbG9jYXRpb25Gcm9tT2Zmc2V0cyhmaWxlbmFtZSwgc291cmNlLCBpbnZhbGlkT2Zmc2V0LCBpbnZhbGlkT2Zmc2V0ICsgMSksXG4gICAgICBtZXNzYWdlOiBcIlB5dGhvbiBzb3VyY2UgY29udGFpbnMgYW4gaW52YWxpZCBsb25lIFVURi0xNiBzdXJyb2dhdGUuXCJcbiAgICB9KVxuICB9XG4gIGxldCB0cmVlXG5cbiAgdHJ5IHtcbiAgICB0cmVlID0gcGFyc2VyLnBhcnNlKHNvdXJjZSlcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXR1cm4gcGFyc2VGYWlsdXJlKFwicHl0aG9uXCIsIGVycm9yKVxuICB9XG4gIGNvbnN0IHJvb3QgPSB0cmVlLnJvb3ROb2RlXG5cbiAgdmFsaWRhdGVQYXJzZXJUcmVlKHJvb3QsIGZpbGVuYW1lLCBzb3VyY2UpXG4gIGlmIChyb290LnR5cGUgIT0gXCJtb2R1bGVcIikgdGhyb3cgbmV3IEVycm9yKGBUcmVlLXNpdHRlciByZXR1cm5lZCBQeXRob24gcm9vdCAnJHtyb290LnR5cGV9Jy5gKVxuXG4gIGNvbnN0IGNvbW1lbnRzID0gcm9vdC5kZXNjZW5kYW50c09mVHlwZShcImNvbW1lbnRcIilcbiAgY29uc3QgY29udGV4dCA9IHtjb21tZW50cywgdXNlZEltbXV0YWJsZU1hcmtlcnM6IG5ldyBTZXQoKX1cbiAgY29uc3QgZnVuY3Rpb25zID0gW11cbiAgY29uc3QgZW50cnlOb2RlcyA9IFtdXG4gIGxldCBzYXdFbnRyeSA9IGZhbHNlXG5cbiAgZm9yIChjb25zdCBub2RlIG9mIHJvb3QubmFtZWRDaGlsZHJlbikge1xuICAgIGlmIChub2RlLnR5cGUgPT0gXCJjb21tZW50XCIpIGNvbnRpbnVlXG4gICAgaWYgKG5vZGUudHlwZSA9PSBcImZ1bmN0aW9uX2RlZmluaXRpb25cIiAmJiAhc2F3RW50cnkpIGZ1bmN0aW9ucy5wdXNoKGNvbnZlcnRGdW5jdGlvbihub2RlLCBjb250ZXh0LCBmaWxlbmFtZSwgc291cmNlKSlcbiAgICBlbHNlIHtcbiAgICAgIHNhd0VudHJ5ID0gdHJ1ZVxuICAgICAgZW50cnlOb2Rlcy5wdXNoKG5vZGUpXG4gICAgfVxuICB9XG4gIGNvbnN0IGxvY2F0aW9uID0gbW9kdWxlTG9jYXRpb24oZmlsZW5hbWUsIHNvdXJjZSlcbiAgY29uc3QgZW50cnlMb2NhdGlvbiA9IGVudHJ5Tm9kZXMubGVuZ3RoID09IDAgPyBsb2NhdGlvbiA6IGxvY2F0aW9uRnJvbU9mZnNldHMoXG4gICAgZmlsZW5hbWUsXG4gICAgc291cmNlLFxuICAgIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQoc291cmNlLCBlbnRyeU5vZGVzWzBdLnN0YXJ0SW5kZXgpLFxuICAgIGJpbmRpbmdJbmRleFRvVXRmMTZPZmZzZXQoc291cmNlLCBlbnRyeU5vZGVzLmF0KC0xKT8uZW5kSW5kZXggPz8gcm9vdC5lbmRJbmRleClcbiAgKVxuICBjb25zdCBlbnRyeVZpc2libGUgPSBuZXcgU2V0KClcbiAgY29uc3QgZW50cnlIYXNQYXNzID0gZW50cnlOb2Rlcy5zb21lKChub2RlKSA9PiBub2RlLnR5cGUgPT0gXCJwYXNzX3N0YXRlbWVudFwiKVxuXG4gIGlmIChlbnRyeUhhc1Bhc3MgJiYgZW50cnlOb2Rlcy5sZW5ndGggIT0gMSkge1xuICAgIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBcInRvcC1sZXZlbCBwYXNzIHdpdGggZXhlY3V0YWJsZSBzaWJsaW5nc1wiLCBlbnRyeUxvY2F0aW9uKVxuICB9XG4gIGNvbnN0IGVudHJ5QmxvY2sgPSB7XG4gICAga2luZDogLyoqIEB0eXBlIHtjb25zdH0gKi8gKFwiQmxvY2tcIiksXG4gICAgbG9jYXRpb246IGVudHJ5TG9jYXRpb24sXG4gICAgc3RhdGVtZW50czogZW50cnlIYXNQYXNzID8gW10gOiBlbnRyeU5vZGVzLm1hcCgobm9kZSkgPT4gY29udmVydFN0YXRlbWVudChub2RlLCBjb250ZXh0LCBlbnRyeVZpc2libGUsIGZpbGVuYW1lLCBzb3VyY2UpKVxuICB9XG4gIGNvbnN0IHVudXNlZE1hcmtlciA9IGNvbW1lbnRzLmZpbmQoKGNvbW1lbnQpID0+IGNvbW1lbnQudGV4dCA9PSBpbW11dGFibGVNYXJrZXIgJiYgIWNvbnRleHQudXNlZEltbXV0YWJsZU1hcmtlcnMuaGFzKGNvbW1lbnQpKVxuXG4gIGlmICh1bnVzZWRNYXJrZXIpIHJldHVybiB1bnN1cHBvcnRlZFN5bnRheChcInB5dGhvblwiLCBcInVuYXR0YWNoZWQgaW1tdXRhYmxlIG1hcmtlclwiLCBub2RlTG9jYXRpb24odW51c2VkTWFya2VyLCBmaWxlbmFtZSwgc291cmNlKSlcbiAgaWYgKGZ1bmN0aW9ucy5sZW5ndGggPT0gMCkgcmV0dXJuIHVuc3VwcG9ydGVkU3ludGF4KFwicHl0aG9uXCIsIFwibW9kdWxlIHdpdGhvdXQgYSBmdW5jdGlvblwiLCBsb2NhdGlvbilcblxuICByZXR1cm4ge1xuICAgIGVudHJ5UG9pbnQ6IHtib2R5OiBlbnRyeUJsb2NrLCBraW5kOiBcIkVudHJ5UG9pbnRcIiwgbG9jYXRpb246IGVudHJ5TG9jYXRpb259LFxuICAgIGZ1bmN0aW9ucyxcbiAgICBraW5kOiBcIk1vZHVsZVwiLFxuICAgIGxvY2F0aW9uXG4gIH1cbn1cbiJdfQ==
|