From 4fb81dd42d2ed06bf71beeec3af0f4645e09dfc6 Mon Sep 17 00:00:00 2001 From: Greg Magolan Date: Mon, 30 Sep 2019 12:26:05 -0700 Subject: [PATCH] feat(typescript): add JSNamedModuleInfo provider to ts_library outputs All rules that require devmode named sources are updated to use JSNamedModuleInfo. The rules affected are karma, protractor, ts_devserver, ts_proto_library (in labs) & npm_package. BREAKING CHANGES: The following breaking changes are from internal details so they should not affect most users, however, some downstream projects such as Angular rely on these and will need to be updated accordingly when updating to the next release. * `sources_aspect` from `/internal/node/node.bzl` and `/internal/common/sources_aspect.bzl` is removed; its functionality was duplicate to what JSNamedModuleInfo providers * NodeModuleSources is removed and its `sources` field is moved to NodeModuleInfo; sources in the `scripts` field are now provided by JSNamedModuleInfo * node_module_library `scripts` attribute renamed to `named_sources` * `collect_node_modules_aspect` renamed to just `node_modules_aspect` --- internal/common/devmode_js_sources.bzl | 26 ++++--- internal/common/node_module_info.bzl | 73 +++++++------------ internal/common/sources_aspect.bzl | 61 ---------------- internal/linker/link_node_modules.bzl | 6 +- internal/node.bzl | 2 - internal/node/node.bzl | 29 +++++--- internal/node/npm_package_bin.bzl | 16 +++- internal/npm_install/generate_build_file.js | 16 ++-- internal/npm_install/generate_build_file.ts | 14 ++-- internal/npm_install/node_module_library.bzl | 38 +++++----- internal/npm_install/npm_umd_bundle.bzl | 6 +- .../golden/@angular/core/BUILD.bazel.golden | 2 +- internal/npm_package/npm_package.bzl | 40 +++++----- internal/npm_package/test/BUILD.bazel | 9 +-- internal/npm_package/test/foo.d.ts | 1 - internal/npm_package/test/foo.js | 1 - internal/npm_package/test/foo.ts | 1 + internal/npm_package/test/npm_package.spec.js | 4 +- internal/rollup/rollup_bundle.bzl | 21 +++--- packages/jasmine/docs/BUILD.bazel | 1 + packages/karma/docs/BUILD.bazel | 1 + packages/karma/src/karma_web_test.bzl | 72 ++++++++++-------- packages/karma/src/web_test.bzl | 4 +- .../labs/src/protobufjs/ts_proto_library.bzl | 5 +- packages/protractor/docs/BUILD.bazel | 1 + .../protractor/src/protractor_web_test.bzl | 68 ++++++++++------- .../protractor/test/protractor-2/BUILD.bazel | 11 ++- .../typescript/src/internal/build_defs.bzl | 30 ++++---- .../src/internal/devserver/ts_devserver.bzl | 37 ++++++---- .../devmode_consumer/devmode_consumer.bzl | 21 +++--- providers.bzl | 45 ++++++++++++ 31 files changed, 345 insertions(+), 317 deletions(-) delete mode 100644 internal/common/sources_aspect.bzl delete mode 100644 internal/npm_package/test/foo.d.ts delete mode 100644 internal/npm_package/test/foo.js create mode 100644 internal/npm_package/test/foo.ts diff --git a/internal/common/devmode_js_sources.bzl b/internal/common/devmode_js_sources.bzl index f19d32b7c5..8c5b348f69 100644 --- a/internal/common/devmode_js_sources.bzl +++ b/internal/common/devmode_js_sources.bzl @@ -17,7 +17,7 @@ Outputs a manifest file with the sources listed. """ -load(":sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") # Avoid using non-normalized paths (workspace/../other_workspace/path) def _to_manifest_path(ctx, file): @@ -27,26 +27,30 @@ def _to_manifest_path(ctx, file): return ctx.workspace_name + "/" + file.short_path def _devmode_js_sources_impl(ctx): - files = depset() - - for d in ctx.attr.deps: - if hasattr(d, "node_sources"): - files = depset(transitive = [files, d.node_sources]) - elif hasattr(d, "files"): - files = depset(transitive = [files, d.files]) + sources_depsets = [] + for dep in ctx.attr.deps: + if JSNamedModuleInfo in dep: + sources_depsets.append(dep[JSNamedModuleInfo].sources) + if hasattr(dep, "files"): + sources_depsets.append(dep.files) + sources = depset(transitive = sources_depsets) ctx.actions.write(ctx.outputs.manifest, "".join([ _to_manifest_path(ctx, f) + "\n" - for f in files.to_list() + for f in sources.to_list() + if f.path.endswith(".js") or f.path.endswith(".mjs") ])) - return [DefaultInfo(files = files)] + + return [DefaultInfo( + files = sources, + runfiles = ctx.runfiles(transitive_files = sources), + )] devmode_js_sources = rule( implementation = _devmode_js_sources_impl, attrs = { "deps": attr.label_list( allow_files = True, - aspects = [sources_aspect], ), }, outputs = { diff --git a/internal/common/node_module_info.bzl b/internal/common/node_module_info.bzl index 044daed558..4f5cc8f95c 100644 --- a/internal/common/node_module_info.bzl +++ b/internal/common/node_module_info.bzl @@ -12,63 +12,40 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""NodeModuleInfo & NodeModuleSources providers and apsect to collect node_modules from deps. +"""NodeModuleInfo providers and apsect to collect node_modules from deps. """ -# NodeModuleInfo provider is only provided by targets that are npm dependencies by the -# `node_module_library` rule. This provider is currently used by different rules to filter out -# npm dependencies such as -# ``` -# [d for d in ctx.attr.deps if not NodeModuleInfo in d] -# ``` -# in `packages/typescript/internal/build_defs.bzl` or -# ``` -# hasattr(target, "files") and not NodeModuleInfo in target: -# ``` -# in `internal/common/sources_aspect.bzl`. -# Similar filtering is done in downstream repositories such as angular/angular so this provider -# needs to go through a deprecation period before it can be phased out. -NodeModuleInfo = provider( - doc = "Provides information about npm dependencies installed with yarn_install and npm_install rules", - fields = { - "workspace": "The workspace name that the npm dependencies are provided from", - }, -) - -# NodeModuleSources provider is provided by targets that are npm dependencies by the +# NodeModuleInfo provider is provided by targets that are npm dependencies by the # `node_module_library` rule as well as other targets that have direct or transitive deps on -# `node_module_library` targets via the `collect_node_modules_aspect` below. -# TODO: rename to NodeModuleSourcesInfo so name doesn't trigger name-conventions warning -# buildozer: disable=name-conventions -NodeModuleSources = provider( - doc = "Provides sources for npm dependencies installed with yarn_install and npm_install rules", +# `node_module_library` targets via the `node_modules_aspect` below. +NodeModuleInfo = provider( + doc = "Provides information about npm dependencies", fields = { - "scripts": "Source files that are javascript named-UMD or named-AMD modules for use in rules such as ts_devserver", - "sources": "Source files that are npm dependencies", + "sources": "Source files that are direct & transitive npm depedendencies", "workspace": "The workspace name that the npm dependencies are provided from", }, ) -def _collect_node_modules_aspect_impl(target, ctx): - nm_wksp = None - - if NodeModuleSources in target: - return [] +def _node_modules_aspect_impl(target, ctx): + providers = [] - if hasattr(ctx.rule.attr, "deps"): + # provide NodeModuleInfo if it is not already provided there are NodeModuleInfo deps + if not NodeModuleInfo in target: sources = depset() - for dep in ctx.rule.attr.deps: - if NodeModuleSources in dep: - if nm_wksp and dep[NodeModuleSources].workspace != nm_wksp: - fail("All npm dependencies need to come from a single workspace. Found '%s' and '%s'." % (nm_wksp, dep[NodeModuleSources].workspace)) - nm_wksp = dep[NodeModuleSources].workspace - sources = depset(transitive = [dep[NodeModuleSources].sources, sources]) - if sources: - return [NodeModuleSources(sources = sources, workspace = nm_wksp)] - - return [] - -collect_node_modules_aspect = aspect( - implementation = _collect_node_modules_aspect_impl, + nm_wksp = None + if hasattr(ctx.rule.attr, "deps"): + for dep in ctx.rule.attr.deps: + if NodeModuleInfo in dep: + if nm_wksp and dep[NodeModuleInfo].workspace != nm_wksp: + fail("All npm dependencies need to come from a single workspace. Found '%s' and '%s'." % (nm_wksp, dep[NodeModuleInfo].workspace)) + nm_wksp = dep[NodeModuleInfo].workspace + sources = depset(transitive = [dep[NodeModuleInfo].sources, sources]) + if nm_wksp: + providers.extend([NodeModuleInfo(sources = sources, workspace = nm_wksp)]) + + return providers + +node_modules_aspect = aspect( + _node_modules_aspect_impl, attr_aspects = ["deps"], ) diff --git a/internal/common/sources_aspect.bzl b/internal/common/sources_aspect.bzl deleted file mode 100644 index 2da1c284ed..0000000000 --- a/internal/common/sources_aspect.bzl +++ /dev/null @@ -1,61 +0,0 @@ -# Copyright 2017 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Aspect to collect es5 js sources and scripts from deps. -""" - -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "NodeModuleSources") - -def _sources_aspect_impl(target, ctx): - # TODO(kyliau): node_sources here is a misnomer because it implies that - # the sources have got something to do with node modules. In fact, - # node_sources collects es5 output from typescript and "javascript-like" - # targets that are *not* node modules. This name is kept as-is to maintain - # compatibility with existing rules but should be renamed and cleaned up. - node_sources = depset() - - # dev_scripts is a collection of "scripts" from "node-module-like" targets - # such as `node_module_library` - dev_scripts = depset() - - # Note layering: until we have JS interop providers, this needs to know how to - # get TypeScript outputs. - if hasattr(target, "typescript"): - node_sources = depset(transitive = [node_sources, target.typescript.es5_sources]) - elif hasattr(target, "files") and not NodeModuleInfo in target: - # Sources from npm fine grained deps should not be included - node_sources = depset( - [f for f in target.files.to_list() if f.path.endswith(".js")], - transitive = [node_sources], - ) - - if NodeModuleSources in target: - dev_scripts = depset(target[NodeModuleSources].scripts) - - if hasattr(ctx.rule.attr, "deps"): - for dep in ctx.rule.attr.deps: - if hasattr(dep, "node_sources"): - node_sources = depset(transitive = [node_sources, dep.node_sources]) - if hasattr(dep, "dev_scripts"): - dev_scripts = depset(transitive = [dev_scripts, dep.dev_scripts]) - - return struct( - node_sources = node_sources, - dev_scripts = dev_scripts, - ) - -sources_aspect = aspect( - _sources_aspect_impl, - attr_aspects = ["deps"], -) diff --git a/internal/linker/link_node_modules.bzl b/internal/linker/link_node_modules.bzl index ef49e99902..d974c6c26b 100644 --- a/internal/linker/link_node_modules.bzl +++ b/internal/linker/link_node_modules.bzl @@ -10,7 +10,7 @@ linker, which uses the mappings to link a node_modules directory for runtimes to locate all the first-party packages. """ -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleSources") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo") def _debug(vars, *args): if "VERBOSE_LOGS" in vars.keys(): @@ -42,8 +42,8 @@ def register_node_modules_linker(ctx, args, inputs): # Look through data/deps attributes to find... for dep in getattr(ctx.attr, "data", []) + getattr(ctx.attr, "deps", []): # ...the root directory for the third-party node_modules; we'll symlink the local "node_modules" to it - if NodeModuleSources in dep: - possible_root = "/".join([dep[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in dep: + possible_root = "/".join([dep[NodeModuleInfo].workspace, "node_modules"]) if not node_modules_root: node_modules_root = possible_root elif node_modules_root != possible_root: diff --git a/internal/node.bzl b/internal/node.bzl index c8115f6f82..cd80d47fdf 100644 --- a/internal/node.bzl +++ b/internal/node.bzl @@ -23,7 +23,5 @@ load( "//internal/common:expand_into_runfiles.bzl", _expand_location_into_runfiles = "expand_location_into_runfiles", ) -load("//internal/common:sources_aspect.bzl", _sources_aspect = "sources_aspect") -sources_aspect = _sources_aspect expand_location_into_runfiles = _expand_location_into_runfiles diff --git a/internal/node/node.bzl b/internal/node/node.bzl index 3cb0dd3cd7..462c9bb48d 100644 --- a/internal/node/node.bzl +++ b/internal/node/node.bzl @@ -20,10 +20,11 @@ They support module mapping: any targets in the transitive dependencies with a `module_name` attribute can be `require`d by that name. """ -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleSources", "collect_node_modules_aspect") +load("@build_bazel_rules_nodejs//:declaration_provider.bzl", "DeclarationInfo") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") load("//internal/common:expand_into_runfiles.bzl", "expand_location_into_runfiles") load("//internal/common:module_mappings.bzl", "module_mappings_runtime_aspect") -load("//internal/common:sources_aspect.bzl", "sources_aspect") load("//internal/common:windows_utils.bzl", "create_windows_native_launcher_script", "is_windows") def _trim_package_node_modules(package_name): @@ -48,8 +49,8 @@ def _compute_node_modules_root(ctx): """ node_modules_root = None if ctx.attr.node_modules: - if NodeModuleSources in ctx.attr.node_modules: - node_modules_root = "/".join([ctx.attr.node_modules[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in ctx.attr.node_modules: + node_modules_root = "/".join([ctx.attr.node_modules[NodeModuleInfo].workspace, "node_modules"]) elif ctx.files.node_modules: # ctx.files.node_modules is not an empty list workspace = ctx.attr.node_modules.label.workspace_root.split("/")[1] if ctx.attr.node_modules.label.workspace_root else ctx.workspace_name @@ -59,8 +60,8 @@ def _compute_node_modules_root(ctx): "node_modules", ] if f]) for d in ctx.attr.data: - if NodeModuleSources in d: - possible_root = "/".join([d[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in d: + possible_root = "/".join([d[NodeModuleInfo].workspace, "node_modules"]) if not node_modules_root: node_modules_root = possible_root elif node_modules_root != possible_root: @@ -130,10 +131,10 @@ def _nodejs_binary_impl(ctx): node_modules = depset(ctx.files.node_modules) # Also include files from npm fine grained deps as inputs. - # These deps are identified by the NodeModuleSources provider. + # These deps are identified by the NodeModuleInfo provider. for d in ctx.attr.data: - if NodeModuleSources in d: - node_modules = depset(transitive = [node_modules, d[NodeModuleSources].sources]) + if NodeModuleInfo in d: + node_modules = depset(transitive = [node_modules, d[NodeModuleInfo].sources]) # Using a depset will allow us to avoid flattening files and sources # inside this loop. This should reduce the performances hits, @@ -141,8 +142,12 @@ def _nodejs_binary_impl(ctx): sources = depset() for d in ctx.attr.data: - if hasattr(d, "node_sources"): - sources = depset(transitive = [sources, d.node_sources]) + if DeclarationInfo in d: + sources = depset(transitive = [sources, d[DeclarationInfo].transitive_declarations]) + + # TODO: switch to JSModuleInfo when it is available + if JSNamedModuleInfo in d: + sources = depset(transitive = [sources, d[JSNamedModuleInfo].sources]) if hasattr(d, "files"): sources = depset(transitive = [sources, d.files]) @@ -262,7 +267,7 @@ _NODEJS_EXECUTABLE_ATTRS = { "data": attr.label_list( doc = """Runtime dependencies which may be loaded during execution.""", allow_files = True, - aspects = [sources_aspect, module_mappings_runtime_aspect, collect_node_modules_aspect], + aspects = [node_modules_aspect, module_mappings_runtime_aspect], ), "default_env_vars": attr.string_list( doc = """Default environment variables that are added to `configuration_env_vars`. diff --git a/internal/node/npm_package_bin.bzl b/internal/node/npm_package_bin.bzl index 3b40f729a8..8ed3904450 100644 --- a/internal/node/npm_package_bin.bzl +++ b/internal/node/npm_package_bin.bzl @@ -1,5 +1,6 @@ "A generic rule to run a tool that appears in node_modules/.bin" +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "module_mappings_aspect", "register_node_modules_linker") # Note: this API is chosen to match nodejs_binary @@ -7,7 +8,7 @@ load("@build_bazel_rules_nodejs//internal/linker:link_node_modules.bzl", "module _ATTRS = { "outs": attr.output_list(), "args": attr.string_list(mandatory = True), - "data": attr.label_list(allow_files = True, aspects = [module_mappings_aspect]), + "data": attr.label_list(allow_files = True, aspects = [module_mappings_aspect, node_modules_aspect]), "output_dir": attr.bool(), "tool": attr.label( executable = True, @@ -23,6 +24,17 @@ def _expand_location(ctx, s): s = s.replace("$@", "/".join([ctx.bin_dir.path, ctx.label.package, ctx.attr.name])) return ctx.expand_location(s, targets = ctx.attr.data) +def _inputs(ctx): + inputs_depsets = [] + + # Also include files from npm fine grained deps as inputs. + # These deps are identified by the NodeModuleInfo provider. + for d in ctx.attr.data: + if NodeModuleInfo in d: + # Note: we can't avoid calling .to_list() on sources + inputs_depsets.append(d[NodeModuleInfo].sources) + return depset(ctx.files.data, transitive = inputs_depsets).to_list() + def _impl(ctx): if ctx.attr.output_dir and ctx.attr.outs: fail("Only one of output_dir and outs may be specified") @@ -30,7 +42,7 @@ def _impl(ctx): fail("One of output_dir and outs must be specified") args = ctx.actions.args() - inputs = ctx.files.data[:] + inputs = _inputs(ctx) outputs = [] if ctx.attr.output_dir: outputs = [ctx.actions.declare_directory(ctx.attr.name)] diff --git a/internal/npm_install/generate_build_file.js b/internal/npm_install/generate_build_file.js index cd0a728639..162a1598d5 100644 --- a/internal/npm_install/generate_build_file.js +++ b/internal/npm_install/generate_build_file.js @@ -792,14 +792,14 @@ def _maybe(repo_rule, name, **kwargs): const dtsSources = filterFiles(pkg._files, ['.d.ts']); // TODO(gmagolan): add UMD & AMD scripts to scripts even if not an APF package _but_ only if they // are named? - const scripts = getNgApfScripts(pkg); + const namedSources = getNgApfScripts(pkg); const deps = [pkg].concat(pkg._dependencies.filter(dep => dep !== pkg && !dep._isNested)); - let scriptStarlark = ''; - if (scripts.length) { - scriptStarlark = ` + let namedSourcesStarlark = ''; + if (namedSources.length) { + namedSourcesStarlark = ` # subset of srcs that are javascript named-UMD or named-AMD scripts - scripts = [ - ${scripts.map((f) => `"//:node_modules/${pkg._dir}/${f}",`).join('\n ')} + named_sources = [ + ${namedSources.map((f) => `"//:node_modules/${pkg._dir}/${f}",`).join('\n ')} ],`; } let srcsStarlark = ''; @@ -846,7 +846,7 @@ node_module_library( # circular dependencies errors node_module_library( name = "${pkg._name}__contents", - srcs = [":${pkg._name}__files"],${scriptStarlark} + srcs = [":${pkg._name}__files"],${namedSourcesStarlark} ) # ${pkg._name}__typings is the subset of ${pkg._name}__contents that are declarations @@ -1020,4 +1020,4 @@ node_module_library( `; } }); -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVfYnVpbGRfZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2ludGVybmFsL25wbV9pbnN0YWxsL2dlbmVyYXRlX2J1aWxkX2ZpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0lBQUE7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDSCxZQUFZLENBQUM7O0lBR2IseUJBQXlCO0lBQ3pCLDZCQUE2QjtJQUU3QixTQUFTLFdBQVcsQ0FBQyxHQUFHLENBQVE7UUFDOUIsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7WUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLDBCQUEwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVELE1BQU0saUJBQWlCLEdBQUc7Ozs7OztDQU16QixDQUFBO0lBRUQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQixNQUFNLG9CQUFvQixHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDekQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxD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LEdBQUcsSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUVuQyxJQUFJLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFO1lBQ2YsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksSUFBSSxHQUFHLENBQUMsS0FBSyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7WUFDeEYsWUFBWSxHQUFHOzs7VUFHVCxJQUFJO09BQ1AsQ0FBQztTQUNMO1FBRUQsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssY0FBYyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQzNGLFlBQVksR0FBRzs7O1VBR1QsSUFBSTtPQUNQLENBQUM7U0FDTDtRQUVELE9BQU87O21DQUUwQixLQUFLOztjQUUxQixLQUFLLEtBQUssWUFBWSxHQUFHLFlBQVk7OztDQUdsRCxDQUFDO0lBQ0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCAyMDE3IFRoZSBCYXplbCBBdXRob3JzLiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKlxuICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0XG4gKiAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZVxuICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gXCJBUyBJU1wiIEJBU0lTLFxuICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuXG4gKiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnMgYW5kXG4gKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS5cbiAqL1xuLyoqXG4gKiBAZmlsZW92ZXJ2aWV3IFRoaXMgc2NyaXB0IGdlbmVyYXRlcyBCVUlMRC5iYXplbCBmaWxlcyBieSBhbmFseXppbmdcbiAqIHRoZSBub2RlX21vZHVsZXMgZm9sZGVyIGxheWVkIG91dCBieSB5YXJuIG9yIG5wbS4gSXQgZ2VuZXJhdGVzXG4gKiBmaW5lIGdyYWluZWQgQmF6ZWwgYG5vZGVfbW9kdWxlX2xpYnJhcnlgIHRhcmdldHMgZm9yIGVhY2ggcm9vdCBucG0gcGFja2FnZVxuICogYW5kIGFsbCBmaWxlcyBmb3IgdGhhdCBwYWNrYWdlIGFuZCBpdHMgdHJhbnNpdGl2ZSBkZXBzIGFyZSBpbmNsdWRlZFxuICogaW4gdGhlIHRhcmdldC4gRm9yIGV4YW1wbGUsIGBAPHdvcmtzcGFjZT4vL2phc21pbmVgIHdvdWxkXG4gKiBpbmNsdWRlIGFsbCBmaWxlcyBpbiB0aGUgamFzbWluZSBucG0gcGFja2FnZSBhbmQgYWxsIG9mIGl0c1xuICogdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMuXG4gKlxuICogbm9kZWpzX2JpbmFyeSB0YXJnZXRzIGFyZSBhbHNvIGdlbmVyYXRlZCBmb3IgYWxsIGBiaW5gIHNjcmlwdHNcbiAqIGluIGVhY2ggcGFja2FnZS4gRm9yIGV4YW1wbGUsIHRoZSBgQDx3b3Jrc3BhY2U+Ly9qYXNtaW5lL2JpbjpqYXNtaW5lYFxuICogdGFyZ2V0IHdpbGwgYmUgZ2VuZXJhdGVkIGZvciB0aGUgYGphc21pbmVgIGJpbmFyeSBpbiB0aGUgYGphc21pbmVgXG4gKiBucG0gcGFja2FnZS5cbiAqXG4gKiBBZGRpdGlvbmFsbHksIGEgYEA8d29ya3NwYWNlPi8vOm5vZGVfbW9kdWxlc2AgYG5vZGVfbW9kdWxlX2xpYnJhcnlgXG4gKiBpcyBnZW5lcmF0ZWQgdGhhdCBpbmNsdWRlcyBhbGwgcGFja2FnZXMgdW5kZXIgbm9kZV9tb2R1bGVzXG4gKiBhcyB3ZWxsIGFzIHRoZSAuYmluIGZvbGRlci5cbiAqXG4gKiBUaGlzIHdvcmsgaXMgYmFzZWQgb2ZmIHRoZSBmaW5lIGdyYWluZWQgZGVwcyBjb25jZXB0cyBpblxuICogaHR0cHM6Ly9naXRodWIuY29tL3B1YnJlZi9ydWxlc19ub2RlIGRldmVsb3BlZCBieSBAcGNqLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vZG9jdW1lbnQvZC8xQWZqSE1MVnlFX3ZZd2xIU0s3azd5V19JSUdwcFN4c1F0UG05UFRyMXhFb1xuICovXG4ndXNlIHN0cmljdCc7XG5cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcblxuZnVuY3Rpb24gbG9nX3ZlcmJvc2UoLi4ubTogYW55W10pIHtcbiAgaWYgKCEhcHJvY2Vzcy5lbnZbJ1ZFUkJPU0VfTE9HUyddKSBjb25zb2xlLmVycm9yKCdbZ2VuZXJhdGVfYnVpbGRfZmlsZS5qc10nLCAuLi5tKTtcbn1cblxuY29uc3QgQlVJTERfRklMRV9IRUFERVIgPSBgIyBHZW5lcmF0ZWQgZmlsZSBmcm9tIHlhcm5faW5zdGFsbC9ucG1faW5zdGFsbCBydWxlLlxuIyBTZWUgJChiYXplbCBpbmZvIG91dHB1dF9iYXNlKS9leHRlcm5hbC9idWlsZF9iYXplbF9ydWxlc19ub2RlanMvaW50ZXJuYWwvbnBtX2luc3RhbGwvZ2VuZXJhdGVfYnVpbGRfZmlsZS5qc1xuXG4jIEFsbCBydWxlcyBpbiBvdGhlciByZXBvc2l0b3JpZXMgY2FuIHVzZSB0aGVzZSB0YXJnZXRzXG5wYWNrYWdlKGRlZmF1bHRfdmlzaWJpbGl0eSA9IFtcIi8vdmlzaWJpbGl0eTpwdWJsaWNcIl0pXG5cbmBcblxuY29uc3QgYXJncyA9IHByb2Nlc3MuYXJndi5zbGljZSgyKTtcbmNvbnN0IFdPUktTUEFDRSA9IGFyZ3NbMF07XG5jb25zdCBSVUxFX1RZUEUgPSBhcmdzWzFdO1xuY29uc3QgRVJST1JfT05fQkFaRUxfRklMRVMgPSBwYXJzZUludChhcmdzWzJdKTtcbmNvbnN0IExPQ0tfRklMRV9MQUJFTCA9IGFyZ3NbM107XG5jb25zdCBJTkNMVURFRF9GSUxFUyA9IGFyZ3NbNF0gPyBhcmdzWzRdLnNwbGl0KCcsJykgOiBbXTtcbmNvbnN0IERZTkFNSUNfREVQUyA9IEpTT04ucGFyc2UoYXJnc1s1XSB8fCAne30nKTtcblxuaWYgKHJlcXVpcmUubWFpbiA9PT0gbW9kdWxlKSB7XG4gIG1haW4oKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZGlyZWN0b3J5IGFuZCBhbnkgbmVjZXNzYXJ5IHN1YmRpcmVjdG9yaWVzXG4gKiBpZiB0aGV5IGRvIG5vdCBleGlzdC5cbiAqL1xuZnVuY3Rpb24gbWtkaXJwKHA6IHN0cmluZykge1xuICBpZiAoIWZzLmV4aXN0c1N5bmMocCkpIHtcbiAgICBta2RpcnAocGF0aC5kaXJuYW1lKHApKTtcbiAgICBmcy5ta2RpclN5bmMocCk7XG4gIH1cbn1cblxuLyoqXG4gKiBXcml0ZXMgYSBmaWxlLCBmaXJzdCBlbnN1cmluZyB0aGF0IHRoZSBkaXJlY3RvcnkgdG9cbiAqIHdyaXRlIHRvIGV4aXN0cy5cbiAqL1xuZnVuY3Rpb24gd3JpdGVGaWxlU3luYyhwOiBzdHJpbmcsIGNvbnRlbnQ6IHN0cmluZykge1xuICBta2RpcnAocGF0aC5kaXJuYW1lKHApKTtcbiAgZnMud3JpdGVGaWxlU3luYyhwLCBjb250ZW50KTtcbn1cblxuLyoqXG4gKiBNYWluIGVudHJ5cG9pbnQuXG4gKi9cbmZ1bmN0aW9uIG1haW4oKSB7XG4gIC8vIGZpbmQgYWxsIHBhY2thZ2VzIChpbmNsdWRpbmcgcGFja2FnZXMgaW4gbmVzdGVkIG5vZGVfbW9kdWxlcylcbiAgY29uc3QgcGtncyA9IGZpbmRQYWNrYWdlcygpO1xuXG4gIC8vIGZsYXR0ZW4gZGVwZW5kZW5jaWVzXG4gIGZsYXR0ZW5EZXBlbmRlbmNpZXMocGtncyk7XG5cbiAgLy8gZ2VuZXJhdGUgQmF6ZWwgd29ya3NwYWNlc1xuICBnZW5lcmF0ZUJhemVsV29ya3NwYWNlcyhwa2dzKVxuXG4gIC8vIGdlbmVyYXRlIGFsbCBCVUlMRCBmaWxlc1xuICBnZW5lcmF0ZUJ1aWxkRmlsZXMocGtncylcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIG1haW4sXG4gIHByaW50UGFja2FnZUJpbixcbiAgYWRkRHluYW1pY0RlcGVuZGVuY2llcyxcbiAgcHJpbnRJbmRleEJ6bCxcbn07XG5cbi8qKlxuICogR2VuZXJhdGVzIGFsbCBidWlsZCBmaWxlc1xuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUJ1aWxkRmlsZXMocGtnczogRGVwW10pIHtcbiAgZ2VuZXJhdGVSb290QnVpbGRGaWxlKHBrZ3MuZmlsdGVyKHBrZyA9PiAhcGtnLl9pc05lc3RlZCkpXG4gIHBrZ3MuZmlsdGVyKHBrZyA9PiAhcGtnLl9pc05lc3RlZCkuZm9yRWFjaChwa2cgPT4gZ2VuZXJhdGVQYWNrYWdlQnVpbGRGaWxlcyhwa2cpKTtcbiAgZmluZFNjb3BlcygpLmZvckVhY2goc2NvcGUgPT4gZ2VuZXJhdGVTY29wZUJ1aWxkRmlsZXMoc2NvcGUsIHBrZ3MpKTtcbn1cblxuLyoqXG4gKiBGbGF0dGVucyBkZXBlbmRlbmNpZXMgb24gYWxsIHBhY2thZ2VzXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5EZXBlbmRlbmNpZXMocGtnczogRGVwW10pIHtcbiAgY29uc3QgcGtnc01hcCA9IG5ldyBNYXAoKTtcbiAgcGtncy5mb3JFYWNoKHBrZyA9PiBwa2dzTWFwLnNldChwa2cuX2RpciwgcGtnKSk7XG4gIHBrZ3MuZm9yRWFjaChwa2cgPT4gZmxhdHRlblBrZ0RlcGVuZGVuY2llcyhwa2csIHBrZywgcGtnc01hcCkpO1xufVxuXG4vKipcbiAqIEhhbmRsZXMgQmF6ZWwgZmlsZXMgaW4gbnBtIGRpc3RyaWJ1dGlvbnMuXG4gKi9cbmZ1bmN0aW9uIGhpZGVCYXplbEZpbGVzKHBrZzogRGVwKSB7XG4gIGNvbnN0IGhhc0hpZGVCYXplbEZpbGVzID0gaXNEaXJlY3RvcnkoJ25vZGVfbW9kdWxlcy9AYmF6ZWwvaGlkZS1iYXplbC1maWxlcycpO1xuICBwa2cuX2ZpbGVzID0gcGtnLl9maWxlcy5tYXAoZmlsZSA9PiB7XG4gICAgY29uc3QgYmFzZW5hbWUgPSBwYXRoLmJhc2VuYW1lKGZpbGUpO1xuICAgIGNvbnN0IGJhc2VuYW1lVWMgPSBiYXNlbmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgIGlmIChiYXNlbmFtZVVjID09PSAnQlVJTEQnIHx8IGJhc2VuYW1lVWMgPT09ICdCVUlMRC5CQVpFTCcpIHtcbiAgICAgIC8vIElmIGJhemVsIGZpbGVzIGFyZSBkZXRlY3RlZCBhbmQgdGhlcmUgaXMgbm8gQGJhemVsL2hpZGUtYmF6ZWwtZmlsZXMgbnBtXG4gICAgICAvLyBwYWNrYWdlIHRoZW4gZXJyb3Igb3V0IGFuZCBzdWdnZXN0IGFkZGluZyB0aGUgcGFja2FnZS4gSXQgaXMgcG9zc2libGUgdG9cbiAgICAgIC8vIGhhdmUgYmF6ZWwgQlVJTEQgZmlsZXMgd2l0aCB0aGUgcGFja2FnZSBpbnN0YWxsZWQgYXMgaXQncyBwb3N0aW5zdGFsbFxuICAgICAgLy8gc3RlcCwgd2hpY2ggaGlkZXMgYmF6ZWwgQlVJTEQgZmlsZXMsIG9ubHkgcnVucyB3aGVuIHRoZSBAYmF6ZWwvaGlkZS1iYXplbC1maWxlc1xuICAgICAgLy8gaXMgaW5zdGFsbGVkIGFuZCBub3Qgd2hlbiBuZXcgcGFja2FnZXMgYXJlIGFkZGVkICh2aWEgYHlhcm4gYWRkYFxuICAgICAgLy8gZm9yIGV4YW1wbGUpIGFmdGVyIHRoZSBpbml0aWFsIGluc3RhbGwuIEluIHRoaXMgY2FzZSwgaG93ZXZlciwgdGhlIHJlcG8gcnVsZVxuICAgICAgLy8gd2lsbCByZS1ydW4gYXMgdGhlIHBhY2thZ2UuanNvbiAmJiBsb2NrIGZpbGUgaGFzIGNoYW5nZWQgc28gd2UganVzdFxuICAgICAgLy8gaGlkZSB0aGUgYWRkZWQgQlVJTEQgZmlsZXMgZHVyaW5nIHRoZSByZXBvIHJ1bGUgcnVuIGhlcmUgc2luY2UgQGJhemVsL2hpZGUtYmF6ZWwtZmlsZXNcbiAgICAgIC8vIHdhcyBub3QgcnVuLlxuICAgICAgaWYgKCFoYXNIaWRlQmF6ZWxGaWxlcyAmJiBFUlJPUl9PTl9CQVpFTF9GSUxFUykge1xuICAgICAgICBjb25zb2xlLmVycm9yKGBucG0gcGFja2FnZSAnJHtwa2cuX2Rpcn0nIGZyb20gQCR7V09SS1NQQUNFfSAke1JVTEVfVFlQRX0gcnVsZVxuaGFzIGEgQmF6ZWwgQlVJTEQgZmlsZSAnJHtmaWxlfScuIFVzZSB0aGUgQGJhemVsL2hpZGUtYmF6ZWwtZmlsZXMgdXRpbGl0eSB0byBoaWRlIHRoZXNlIGZpbGVzLlxuU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL3J1bGVzX25vZGVqcy9ibG9iL21hc3Rlci9wYWNrYWdlcy9oaWRlLWJhemVsLWZpbGVzL1JFQURNRS5tZFxuZm9yIGluc3RhbGxhdGlvbiBpbnN0cnVjdGlvbnMuYCk7XG4gICAgICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEFsbCBCYXplbCBmaWxlcyBpbiB0aGUgbnBtIGRpc3RyaWJ1dGlvbiBzaG91bGQgYmUgcmVuYW1lZCBieVxuICAgICAgICAvLyBhZGRpbmcgYSBgX2AgcHJlZml4IHNvIHRoYXQgZmlsZSB0YXJnZXRzIGRvbid0IGNyb3NzIHBhY2thZ2UgYm91bmRhcmllcy5cbiAgICAgICAgY29uc3QgbmV3RmlsZSA9IHBhdGgucG9zaXguam9pbihwYXRoLmRpcm5hbWUoZmlsZSksIGBfJHtiYXNlbmFtZX1gKTtcbiAgICAgICAgY29uc3Qgc3JjUGF0aCA9IHBhdGgucG9zaXguam9pbignbm9kZV9tb2R1bGVzJywgcGtnLl9kaXIsIGZpbGUpO1xuICAgICAgICBjb25zdCBkc3RQYXRoID0gcGF0aC5wb3NpeC5qb2luKCdub2RlX21vZHVsZXMnLCBwa2cuX2RpciwgbmV3RmlsZSk7XG4gICAgICAgIGZzLnJlbmFtZVN5bmMoc3JjUGF0aCwgZHN0UGF0aCk7XG4gICAgICAgIHJldHVybiBuZXdGaWxlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmlsZTtcbiAgfSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIHRoZSByb290IEJVSUxEIGZpbGUuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlUm9vdEJ1aWxkRmlsZShwa2dzOiBEZXBbXSkge1xuICBsZXQgZXhwb3J0c1N0YXJsYXJrID0gJyc7XG4gIHBrZ3MuZm9yRWFjaChwa2cgPT4ge3BrZy5fZmlsZXMuZm9yRWFjaChmID0+IHtcbiAgICAgICAgICAgICAgICAgZXhwb3J0c1N0YXJsYXJrICs9IGAgICAgXCJub2RlX21vZHVsZXMvJHtwa2cuX2Rpcn0vJHtmfVwiLFxuYDtcbiAgICAgICAgICAgICAgIH0pfSk7XG5cbiAgbGV0IHNyY3NTdGFybGFyayA9ICcnO1xuICBpZiAocGtncy5sZW5ndGgpIHtcbiAgICBjb25zdCBsaXN0ID0gcGtncy5tYXAocGtnID0+IGBcIi8vJHtwa2cuX2Rpcn06JHtwa2cuX25hbWV9X19maWxlc1wiLGApLmpvaW4oJ1xcbiAgICAgICAgJyk7XG4gICAgc3Jjc1N0YXJsYXJrID0gYFxuICAgICMgZGlyZWN0IHNvdXJjZXMgbGlzdGVkIGZvciBzdHJpY3QgZGVwcyBzdXBwb3J0XG4gICAgc3JjcyA9IFtcbiAgICAgICAgJHtsaXN0fVxuICAgIF0sYDtcbiAgfVxuXG4gIGxldCBkZXBzU3RhcmxhcmsgPSAnJztcbiAgaWYgKHBrZ3MubGVuZ3RoKSB7XG4gICAgY29uc3QgbGlzdCA9IHBrZ3MubWFwKHBrZyA9PiBgXCIvLyR7cGtnLl9kaXJ9OiR7cGtnLl9uYW1lfV9fY29udGVudHNcIixgKS5qb2luKCdcXG4gICAgICAgICcpO1xuICAgIGRlcHNTdGFybGFyayA9IGBcbiAgICAjIGZsYXR0ZW5lZCBsaXN0IG9mIGRpcmVjdCBhbmQgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMgaG9pc3RlZCB0byByb290IGJ5IHRoZSBwYWNrYWdlIG1hbmFnZXJcbiAgICBkZXBzID0gW1xuICAgICAgICAke2xpc3R9XG4gICAgXSxgO1xuICB9XG5cbiAgbGV0IGJ1aWxkRmlsZSA9IEJVSUxEX0ZJTEVfSEVBREVSICtcbiAgICAgIGBsb2FkKFwiQGJ1aWxkX2JhemVsX3J1bGVzX25vZGVqcy8vaW50ZXJuYWwvbnBtX2luc3RhbGw6bm9kZV9tb2R1bGVfbGlicmFyeS5iemxcIiwgXCJub2RlX21vZHVsZV9saWJyYXJ5XCIpXG5cbmV4cG9ydHNfZmlsZXMoW1xuJHtleHBvcnRzU3Rhcmxhcmt9XSlcblxuIyBUaGUgbm9kZV9tb2R1bGVzIGRpcmVjdG9yeSBpbiBvbmUgY2F0Y2gtYWxsIG5vZGVfbW9kdWxlX2xpYnJhcnkuXG4jIE5COiBVc2luZyB0aGlzIHRhcmdldCBtYXkgaGF2ZSBiYWQgcGVyZm9ybWFuY2UgaW1wbGljYXRpb25zIGlmXG4jIHRoZXJlIGFyZSBtYW55IGZpbGVzIGluIHRhcmdldC5cbiMgU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL2JhemVsL2lzc3Vlcy81MTUzLlxubm9kZV9tb2R1bGVfbGlicmFyeShcbiAgICBuYW1lID0gXCJub2RlX21vZHVsZXNcIiwke3NyY3NTdGFybGFya30ke2RlcHNTdGFybGFya31cbilcblxuYFxuXG4gIC8vIEFkZCB0aGUgbWFudWFsIGJ1aWxkIGZpbGUgY29udGVudHMgaWYgdGhleSBleGlzdHNcbiAgdHJ5IHtcbiAgICBidWlsZEZpbGUgKz0gZnMucmVhZEZpbGVTeW5jKGBtYW51YWxfYnVpbGRfZmlsZV9jb250ZW50c2AsIHtlbmNvZGluZzogJ3V0ZjgnfSk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgfVxuXG4gIHdyaXRlRmlsZVN5bmMoJ0JVSUxELmJhemVsJywgYnVpbGRGaWxlKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYWxsIEJVSUxEICYgYnpsIGZpbGVzIGZvciBhIHBhY2thZ2UuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlUGFja2FnZUJ1aWxkRmlsZXMocGtnOiBEZXApIHtcbiAgbGV0IGJ1aWxkRmlsZSA9IHByaW50UGFja2FnZShwa2cpO1xuXG4gIGNvbnN0IGJpbkJ1aWxkRmlsZSA9IHByaW50UGFja2FnZUJpbihwa2cpO1xuICBpZiAoYmluQnVpbGRGaWxlLmxlbmd0aCkge1xuICAgIHdyaXRlRmlsZVN5bmMoXG4gICAgICAgIHBhdGgucG9zaXguam9pbihwa2cuX2RpciwgJ2JpbicsICdCVUlMRC5iYXplbCcpLCBCVUlMRF9GSUxFX0hFQURFUiArIGJpbkJ1aWxkRmlsZSk7XG4gIH1cblxuICBjb25zdCBpbmRleEZpbGUgPSBwcmludEluZGV4QnpsKHBrZyk7XG4gIGlmIChpbmRleEZpbGUubGVuZ3RoKSB7XG4gICAgd3JpdGVGaWxlU3luYyhwYXRoLnBvc2l4LmpvaW4ocGtnLl9kaXIsICdpbmRleC5iemwnKSwgaW5kZXhGaWxlKTtcbiAgICBidWlsZEZpbGUgPSBgJHtidWlsZEZpbGV9XG4jIEZvciBpbnRlZ3JhdGlvbiB0ZXN0aW5nXG5leHBvcnRzX2ZpbGVzKFtcImluZGV4LmJ6bFwiXSlcbmA7XG4gIH1cblxuICB3cml0ZUZpbGVTeW5jKHBhdGgucG9zaXguam9pbihwa2cuX2RpciwgJ0JVSUxELmJhemVsJyksIEJVSUxEX0ZJTEVfSEVBREVSICsgYnVpbGRGaWxlKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBpbnN0YWxsXzx3b3Jrc3BhY2VfbmFtZT4uYnpsIGZpbGVzIHdpdGggZnVuY3Rpb24gdG8gaW5zdGFsbCBlYWNoIHdvcmtzcGFjZS5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVCYXplbFdvcmtzcGFjZXMocGtnczogRGVwW10pIHtcbiAgY29uc3Qgd29ya3NwYWNlczogQmFnPHN0cmluZz4gPSB7fTtcblxuICBmb3IgKGNvbnN0IHBrZyBvZiBwa2dzKSB7XG4gICAgaWYgKCFwa2cuYmF6ZWxXb3Jrc3BhY2VzKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHdvcmtzcGFjZSBvZiBPYmplY3Qua2V5cyhwa2cuYmF6ZWxXb3Jrc3BhY2VzKSkge1xuICAgICAgLy8gQSBiYXplbCB3b3Jrc3BhY2UgY2FuIG9ubHkgYmUgc2V0dXAgYnkgb25lIG5wbSBwYWNrYWdlXG4gICAgICBpZiAod29ya3NwYWNlc1t3b3Jrc3BhY2VdKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICBgQ291bGQgbm90IHNldHVwIEJhemVsIHdvcmtzcGFjZSAke3dvcmtzcGFjZX0gcmVxdWVzdGVkIGJ5IG5wbSBgICtcbiAgICAgICAgICAgIGBwYWNrYWdlICR7cGtnLl9kaXJ9QCR7cGtnLnZlcnNpb259LiBBbHJlYWR5IHNldHVwIGJ5ICR7d29ya3NwYWNlc1t3b3Jrc3BhY2VdfWApO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9XG5cbiAgICAgIGdlbmVyYXRlQmF6ZWxXb3Jrc3BhY2UocGtnLCB3b3Jrc3BhY2UpO1xuXG4gICAgICAvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIG5wbSBwYWNrYWdlIHNldHVwIHRoaXMgYmF6ZWwgd29ya3NwYWNlIGZvciBsYXRlciB1c2VcbiAgICAgIHdvcmtzcGFjZXNbd29ya3NwYWNlXSA9IGAke3BrZy5fZGlyfUAke3BrZy52ZXJzaW9ufWA7XG4gICAgfVxuICB9XG5cbiAgLy8gRmluYWxseSBnZW5lcmF0ZSBpbnN0YWxsX2JhemVsX2RlcGVuZGVuY2llcy5iemxcbiAgZ2VuZXJhdGVJbnN0YWxsQmF6ZWxEZXBlbmRlbmNpZXMoT2JqZWN0LmtleXMod29ya3NwYWNlcykpO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGluc3RhbGxfPHdvcmtzcGFjZT4uYnpsIGZpbGUgd2l0aCBmdW5jdGlvbiB0byBpbnN0YWxsIHRoZSB3b3Jrc3BhY2UuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlQmF6ZWxXb3Jrc3BhY2UocGtnOiBEZXAsIHdvcmtzcGFjZTogc3RyaW5nKSB7XG4gIGxldCBiemxGaWxlID0gYCMgR2VuZXJhdGVkIGJ5IHRoZSB5YXJuX2luc3RhbGwvbnBtX2luc3RhbGwgcnVsZVxubG9hZChcIkBidWlsZF9iYXplbF9ydWxlc19ub2RlanMvL2ludGVybmFsL2NvcHlfcmVwb3NpdG9yeTpjb3B5X3JlcG9zaXRvcnkuYnpsXCIsIFwiY29weV9yZXBvc2l0b3J5XCIpXG5cbmRlZiBfbWF5YmUocmVwb19ydWxlLCBuYW1lLCAqKmt3YXJncyk6XG4gICAgaWYgbmFtZSBub3QgaW4gbmF0aXZlLmV4aXN0aW5nX3J1bGVzKCk6XG4gICAgICAgIHJlcG9fcnVsZShuYW1lID0gbmFtZSwgKiprd2FyZ3MpXG5gO1xuXG4gIGNvbnN0IHJvb3RQYXRoID0gcGtnLmJhemVsV29ya3NwYWNlc1t3b3Jrc3BhY2VdLnJvb3RQYXRoO1xuICBpZiAoIXJvb3RQYXRoKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgYE1hbGZvcm1lZCBiYXplbFdvcmtzcGFjZXMgYXR0cmlidXRlIGluICR7cGtnLl9kaXJ9QCR7cGtnLnZlcnNpb259LiBgICtcbiAgICAgICAgYE1pc3Npbmcgcm9vdFBhdGggZm9yIHdvcmtzcGFjZSAke3dvcmtzcGFjZX0uYCk7XG4gICAgcHJvY2Vzcy5leGl0KDEpO1xuICB9XG5cbiAgLy8gQ29weSBhbGwgZmlsZXMgZm9yIHRoaXMgd29ya3NwYWNlIHRvIGEgZm9sZGVyIHVuZGVyIF93b3Jrc3BhY2VzXG4gIC8vIHRvIHJlc3RvcmUgdGhlIEJhemVsIGZpbGVzIHdoaWNoIGhhdmUgYmUgcmVuYW1lZCBmcm9tIHRoZSBucG0gcGFja2FnZVxuICBjb25zdCB3b3Jrc3BhY2VTb3VyY2VQYXRoID0gcGF0aC5wb3NpeC5qb2luKCdfd29ya3NwYWNlcycsIHdvcmtzcGFjZSk7XG4gIG1rZGlycCh3b3Jrc3BhY2VTb3VyY2VQYXRoKTtcbiAgcGtnLl9maWxlcy5mb3JFYWNoKGZpbGUgPT4ge1xuICAgIGlmICgvXm5vZGVfbW9kdWxlc1svXFxcXF0vLnRlc3QoZmlsZSkpIHtcbiAgICAgIC8vIGRvbid0IGNvcHkgb3ZlciBuZXN0ZWQgbm9kZV9tb2R1bGVzXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBkZXN0RmlsZSA9IHBhdGgucmVsYXRpdmUocm9vdFBhdGgsIGZpbGUpO1xuICAgIGlmIChkZXN0RmlsZS5zdGFydHNXaXRoKCcuLicpKSB7XG4gICAgICAvLyB0aGlzIGZpbGUgaXMgbm90IHVuZGVyIHRoZSByb290UGF0aFxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBiYXNlbmFtZSA9IHBhdGguYmFzZW5hbWUoZmlsZSk7XG4gICAgY29uc3QgYmFzZW5hbWVVYyA9IGJhc2VuYW1lLnRvVXBwZXJDYXNlKCk7XG4gICAgLy8gQmF6ZWwgQlVJTEQgZmlsZXMgZnJvbSBucG0gZGlzdHJpYnV0aW9uIHdvdWxkIGhhdmUgYmVlbiByZW5hbWVkIGVhcmxpZXIgd2l0aCBhIF8gcHJlZml4IHNvXG4gICAgLy8gd2UgcmVzdG9yZSB0aGUgbmFtZSBvbiB0aGUgY29weVxuICAgIGlmIChiYXNlbmFtZVVjID09PSAnX0JVSUxEJyB8fCBiYXNlbmFtZVVjID09PSAnX0JVSUxELkJBWkVMJykge1xuICAgICAgZGVzdEZpbGUgPSBwYXRoLnBvc2l4LmpvaW4ocGF0aC5kaXJuYW1lKGRlc3RGaWxlKSwgYmFzZW5hbWUuc3Vic3RyKDEpKTtcbiAgICB9XG4gICAgY29uc3Qgc3JjID0gcGF0aC5wb3NpeC5qb2luKCdub2RlX21vZHVsZXMnLCBwa2cuX2RpciwgZmlsZSk7XG4gICAgY29uc3QgZGVzdCA9IHBhdGgucG9zaXguam9pbih3b3Jrc3BhY2VTb3VyY2VQYXRoLCBkZXN0RmlsZSk7XG4gICAgbWtkaXJwKHBhdGguZGlybmFtZShkZXN0KSk7XG4gICAgZnMuY29weUZpbGVTeW5jKHNyYywgZGVzdCk7XG4gIH0pO1xuXG4gIC8vIFdlIGNyZWF0ZSBfYmF6ZWxfd29ya3NwYWNlX21hcmtlciB0aGF0IGlzIHVzZWQgYnkgdGhlIGN1c3RvbSBjb3B5X3JlcG9zaXRvcnlcbiAgLy8gcnVsZSB0byByZXNvbHZlIHRoZSBwYXRoIHRvIHRoZSByZXBvc2l0b3J5IHNvdXJjZSByb290LiBBIHJvb3QgQlVJTEQgZmlsZVxuICAvLyBpcyByZXF1aXJlZCB0byByZWZlcmVuY2UgX2JhemVsX3dvcmtzcGFjZV9tYXJrZXIgYXMgYSB0YXJnZXQgc28gd2UgYWxzbyBjcmVhdGVcbiAgLy8gYW4gZW1wdHkgb25lIGlmIG9uZSBkb2VzIG5vdCBleGlzdC5cbiAgaWYgKCFoYXNSb290QnVpbGRGaWxlKHBrZywgcm9vdFBhdGgpKSB7XG4gICAgd3JpdGVGaWxlU3luYyhcbiAgICAgICAgcGF0aC5wb3NpeC5qb2luKHdvcmtzcGFjZVNvdXJjZVBhdGgsICdCVUlMRC5iYXplbCcpLFxuICAgICAgICAnIyBNYXJrZXIgZmlsZSB0aGF0IHRoaXMgZGlyZWN0b3J5IGlzIGEgYmF6ZWwgcGFja2FnZScpO1xuICB9XG4gIHdyaXRlRmlsZVN5bmMoXG4gICAgICBwYXRoLnBvc2l4LmpvaW4od29ya3NwYWNlU291cmNlUGF0aCwgJ19iYXplbF93b3Jrc3BhY2VfbWFya2VyJyksXG4gICAgICAnIyBNYXJrZXIgZmlsZSB0byB1c2VkIGJ5IGN1c3RvbSBjb3B5X3JlcG9zaXRvcnkgcnVsZScpO1xuXG4gIGJ6bEZpbGUgKz0gYGRlZiBpbnN0YWxsXyR7d29ya3NwYWNlfSgpOlxuICAgIF9tYXliZShcbiAgICAgICAgY29weV9yZXBvc2l0b3J5LFxuICAgICAgICBuYW1lID0gXCIke3dvcmtzcGFjZX1cIixcbiAgICAgICAgbWFya2VyX2ZpbGUgPSBcIkAke1dPUktTUEFDRX0vL193b3Jrc3BhY2VzLyR7d29ya3NwYWNlfTpfYmF6ZWxfd29ya3NwYWNlX21hcmtlclwiLFxuICAgICAgICAjIEVuc3VyZSB0aGF0IGNoYW5nZXMgdG8gdGhlIG5vZGVfbW9kdWxlcyBjYXVzZSB0aGUgY29weSB0byByZS1leGVjdXRlXG4gICAgICAgIGxvY2tfZmlsZSA9IFwiQCR7V09SS1NQQUNFfSR7TE9DS19GSUxFX0xBQkVMfVwiLFxuICAgIClcbmA7XG5cbiAgd3JpdGVGaWxlU3luYyhgaW5zdGFsbF8ke3dvcmtzcGFjZX0uYnpsYCwgYnpsRmlsZSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgaW5zdGFsbF9iYXplbF9kZXBlbmRlbmNpZXMuYnpsIHdpdGggZnVuY3Rpb24gdG8gaW5zdGFsbCBhbGwgd29ya3NwYWNlcy5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVJbnN0YWxsQmF6ZWxEZXBlbmRlbmNpZXMod29ya3NwYWNlczogc3RyaW5nW10pIHtcbiAgbGV0IGJ6bEZpbGUgPSBgIyBHZW5lcmF0ZWQgYnkgdGhlIHlhcm5faW5zdGFsbC9ucG1faW5zdGFsbCBydWxlXG5gO1xuICB3b3Jrc3BhY2VzLmZvckVhY2god29ya3NwYWNlID0+IHtcbiAgICBiemxGaWxlICs9IGBsb2FkKFxcXCI6aW5zdGFsbF8ke3dvcmtzcGFjZX0uYnpsXFxcIiwgXFxcImluc3RhbGxfJHt3b3Jrc3BhY2V9XFxcIilcbmA7XG4gIH0pO1xuICBiemxGaWxlICs9IGBkZWYgaW5zdGFsbF9iYXplbF9kZXBlbmRlbmNpZXMoKTpcbiAgICBcIlwiXCJJbnN0YWxscyBhbGwgd29ya3NwYWNlcyBsaXN0ZWQgaW4gYmF6ZWxXb3Jrc3BhY2VzIG9mIGFsbCBucG0gcGFja2FnZXNcIlwiXCJcbmA7XG4gIHdvcmtzcGFjZXMuZm9yRWFjaCh3b3Jrc3BhY2UgPT4ge1xuICAgIGJ6bEZpbGUgKz0gYCAgICBpbnN0YWxsXyR7d29ya3NwYWNlfSgpXG5gO1xuICB9KTtcblxuICB3cml0ZUZpbGVTeW5jKCdpbnN0YWxsX2JhemVsX2RlcGVuZGVuY2llcy5iemwnLCBiemxGaWxlKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBidWlsZCBmaWxlcyBmb3IgYSBzY29wZS5cbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVTY29wZUJ1aWxkRmlsZXMoc2NvcGU6IHN0cmluZywgcGtnczogRGVwW10pIHtcbiAgY29uc3QgYnVpbGRGaWxlID0gQlVJTERfRklMRV9IRUFERVIgKyBwcmludFNjb3BlKHNjb3BlLCBwa2dzKTtcbiAgd3JpdGVGaWxlU3luYyhwYXRoLnBvc2l4LmpvaW4oc2NvcGUsICdCVUlMRC5iYXplbCcpLCBidWlsZEZpbGUpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHBhdGggaXMgYSBmaWxlLlxuICovXG5mdW5jdGlvbiBpc0ZpbGUocDogc3RyaW5nKSB7XG4gIHJldHVybiBmcy5leGlzdHNTeW5jKHApICYmIGZzLnN0YXRTeW5jKHApLmlzRmlsZSgpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBhIHBhdGggaXMgYW4gbnBtIHBhY2thZ2Ugd2hpY2ggaXMgaXMgYSBkaXJlY3Rvcnkgd2l0aCBhIHBhY2thZ2UuanNvbiBmaWxlLlxuICovXG5mdW5jdGlvbiBpc0RpcmVjdG9yeShwOiBzdHJpbmcpIHtcbiAgcmV0dXJuIGZzLmV4aXN0c1N5bmMocCkgJiYgZnMuc3RhdFN5bmMocCkuaXNEaXJlY3RvcnkoKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIGFsbCB0aGUgZmlsZXMgdW5kZXIgYSBkaXJlY3RvcnkgYXMgcmVsYXRpdmVcbiAqIHBhdGhzIHRvIHRoZSBkaXJlY3RvcnkuXG4gKi9cbmZ1bmN0aW9uIGxpc3RGaWxlcyhyb290RGlyOiBzdHJpbmcsIHN1YkRpcjogc3RyaW5nID0gJycpOiBzdHJpbmdbXSB7XG4gIGNvbnN0IGRpciA9IHBhdGgucG9zaXguam9pbihyb290RGlyLCBzdWJEaXIpO1xuICBpZiAoIWlzRGlyZWN0b3J5KGRpcikpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIGZzLnJlYWRkaXJTeW5jKGRpcilcbiAgICAgIC5yZWR1Y2UoXG4gICAgICAgICAgKGZpbGVzOiBzdHJpbmdbXSwgZmlsZSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZnVsbFBhdGggPSBwYXRoLnBvc2l4LmpvaW4oZGlyLCBmaWxlKTtcbiAgICAgICAgICAgIGNvbnN0IHJlbFBhdGggPSBwYXRoLnBvc2l4LmpvaW4oc3ViRGlyLCBmaWxlKTtcbiAgICAgICAgICAgIGNvbnN0IGlzU3ltYm9saWNMaW5rID0gZnMubHN0YXRTeW5jKGZ1bGxQYXRoKS5pc1N5bWJvbGljTGluaygpO1xuICAgICAgICAgICAgbGV0IHN0YXQ7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICBzdGF0ID0gZnMuc3RhdFN5bmMoZnVsbFBhdGgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICBpZiAoaXNTeW1ib2xpY0xpbmspIHtcbiAgICAgICAgICAgICAgICAvLyBGaWx0ZXIgb3V0IGJyb2tlbiBzeW1ib2xpYyBsaW5rcy4gVGhlc2UgY2F1c2UgZnMuc3RhdFN5bmMoZnVsbFBhdGgpXG4gICAgICAgICAgICAgICAgLy8gdG8gZmFpbCB3aXRoIGBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgLi4uYFxuICAgICAgICAgICAgICAgIHJldHVybiBmaWxlcztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB0aHJvdyBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaXNEaXJlY3RvcnkgPSBzdGF0LmlzRGlyZWN0b3J5KCk7XG4gICAgICAgICAgICBpZiAoaXNEaXJlY3RvcnkgJiYgaXNTeW1ib2xpY0xpbmspIHtcbiAgICAgICAgICAgICAgLy8gRmlsdGVyIG91dCBzeW1ib2xpYyBsaW5rcyB0byBkaXJlY3Rvcmllcy4gQW4gaXNzdWUgaW4geWFybiB2ZXJzaW9uc1xuICAgICAgICAgICAgICAvLyBvbGRlciB0aGFuIDEuMTIuMSBjcmVhdGVzIHN5bWJvbGljIGxpbmtzIHRvIGZvbGRlcnMgaW4gdGhlIC5iaW4gZm9sZGVyXG4gICAgICAgICAgICAgIC8vIHdoaWNoIGxlYWRzIHRvIEJhemVsIHRhcmdldHMgdGhhdCBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMuXG4gICAgICAgICAgICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9ydWxlc19ub2RlanMvaXNzdWVzLzQyOCBhbmRcbiAgICAgICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2JhemVsYnVpbGQvcnVsZXNfbm9kZWpzL2lzc3Vlcy80MzguXG4gICAgICAgICAgICAgIC8vIFRoaXMgaXMgdGVzdGVkIGluIC9lMmUvZmluZV9ncmFpbmVkX3N5bWxpbmtzLlxuICAgICAgICAgICAgICByZXR1cm4gZmlsZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gaXNEaXJlY3RvcnkgPyBmaWxlcy5jb25jYXQobGlzdEZpbGVzKHJvb3REaXIsIHJlbFBhdGgpKSA6IGZpbGVzLmNvbmNhdChyZWxQYXRoKTtcbiAgICAgICAgICB9LFxuICAgICAgICAgIFtdKVxuICAgICAgLy8gRmlsZXMgd2l0aCBzcGFjZXMgKFxceDIwKSBvciB1bmljb2RlIGNoYXJhY3RlcnMgKDxcXHgyMCAmJiA+XFx4N0UpIGFyZSBub3QgYWxsb3dlZCBpblxuICAgICAgLy8gQmF6ZWwgcnVuZmlsZXMuIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9iYXplbC9pc3N1ZXMvNDMyN1xuICAgICAgLmZpbHRlcihmID0+ICEvW15cXHgyMS1cXHg3RV0vLnRlc3QoZikpXG4gICAgICAvLyBXZSByZXR1cm4gYSBzb3J0ZWQgYXJyYXkgc28gdGhhdCB0aGUgb3JkZXIgb2YgZmlsZXNcbiAgICAgIC8vIGlzIHRoZSBzYW1lIHJlZ2FyZGxlc3Mgb2YgcGxhdGZvcm1cbiAgICAgIC5zb3J0KCk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBucG0gcGFja2FnZSBkaXN0cmlidXRpb24gY29udGFpbmVkIGFcbiAqIHJvb3QgL0JVSUxEIG9yIC9CVUlMRC5iYXplbCBmaWxlLlxuICovXG5mdW5jdGlvbiBoYXNSb290QnVpbGRGaWxlKHBrZzogRGVwLCByb290UGF0aDogc3RyaW5nKSB7XG4gIGZvciAoY29uc3QgZmlsZSBvZiBwa2cuX2ZpbGVzKSB7XG4gICAgLy8gQmF6ZWwgZmlsZXMgd291bGQgaGF2ZSBiZWVuIHJlbmFtZWQgZWFybGllciB3aXRoIGEgYF9gIHByZWZpeFxuICAgIGNvbnN0IGZpbGVVYyA9IHBhdGgucmVsYXRpdmUocm9vdFBhdGgsIGZpbGUpLnRvVXBwZXJDYXNlKCk7XG4gICAgaWYgKGZpbGVVYyA9PT0gJ19CVUlMRCcgfHwgZmlsZVVjID09PSAnX0JVSUxELkJBWkVMJykge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuXG5mdW5jdGlvbiBhZGREeW5hbWljRGVwZW5kZW5jaWVzKHBrZ3M6IERlcFtdLCBkeW5hbWljX2RlcHMgPSBEWU5BTUlDX0RFUFMpIHtcbiAgZnVuY3Rpb24gbWF0Y2gobmFtZTogc3RyaW5nLCBwOiBEZXApIHtcbiAgICAvLyBBdXRvbWF0aWNhbGx5IGluY2x1ZGUgZHluYW1pYyBkZXBlbmRlbmN5IG9uIHBsdWdpbnMgb2YgdGhlIGZvcm0gcGtnLXBsdWdpbi1mb29cbiAgICBpZiAobmFtZS5zdGFydHNXaXRoKGAke3AuX21vZHVsZU5hbWV9LXBsdWdpbi1gKSkgcmV0dXJuIHRydWU7XG5cbiAgICBjb25zdCB2YWx1ZSA9IGR5bmFtaWNfZGVwc1twLl9tb2R1bGVOYW1lXTtcbiAgICBpZiAobmFtZSA9PT0gdmFsdWUpIHJldHVybiB0cnVlO1xuXG4gICAgLy8gU3VwcG9ydCB3aWxkY2FyZCBtYXRjaFxuICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS5pbmNsdWRlcygnKicpICYmIG5hbWUuc3RhcnRzV2l0aCh2YWx1ZS5zdWJzdHJpbmcoMCwgdmFsdWUuaW5kZXhPZignKicpKSkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBwa2dzLmZvckVhY2gocCA9PiB7XG4gICAgcC5fZHluYW1pY0RlcGVuZGVuY2llcyA9IHBrZ3MuZmlsdGVyKHggPT4gISF4Ll9tb2R1bGVOYW1lICYmIG1hdGNoKHguX21vZHVsZU5hbWUsIHApKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChkeW4gPT4gYC8vJHtkeW4uX2Rpcn06JHtkeW4uX25hbWV9YCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEZpbmRzIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBwYWNrYWdlcyB1bmRlciBhIGdpdmVuIHBhdGguXG4gKi9cbmZ1bmN0aW9uIGZpbmRQYWNrYWdlcyhwID0gJ25vZGVfbW9kdWxlcycpIHtcbiAgaWYgKCFpc0RpcmVjdG9yeShwKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHBrZ3M6IERlcFtdID0gW107XG5cbiAgY29uc3QgbGlzdGluZyA9IGZzLnJlYWRkaXJTeW5jKHApO1xuXG4gIGNvbnN0IHBhY2thZ2VzID0gbGlzdGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWx0ZXIgb3V0IHNjb3Blc1xuICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGYgPT4gIWYuc3RhcnRzV2l0aCgnQCcpKVxuICAgICAgICAgICAgICAgICAgICAgICAvLyBmaWx0ZXIgb3V0IGZvbGRlcnMgc3VjaCBhcyBgLmJpbmAgd2hpY2ggY2FuIGNyZWF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAvLyBpc3N1ZXMgb24gV2luZG93cyBzaW5jZSB0aGVzZSBhcmUgXCJoaWRkZW5cIiBieSBkZWZhdWx0XG4gICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZiA9PiAhZi5zdGFydHNXaXRoKCcuJykpXG4gICAgICAgICAgICAgICAgICAgICAgIC5tYXAoZiA9PiBwYXRoLnBvc2l4LmpvaW4ocCwgZikpXG4gICAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZiA9PiBpc0RpcmVjdG9yeShmKSk7XG5cbiAgcGFja2FnZXMuZm9yRWFjaChcbiAgICAgIGYgPT4gcGtncy5wdXNoKHBhcnNlUGFja2FnZShmKSwgLi4uZmluZFBhY2thZ2VzKHBhdGgucG9zaXguam9pbihmLCAnbm9kZV9tb2R1bGVzJykpKSk7XG5cbiAgY29uc3Qgc2NvcGVzID0gbGlzdGluZy5maWx0ZXIoZiA9PiBmLnN0YXJ0c1dpdGgoJ0AnKSlcbiAgICAgICAgICAgICAgICAgICAgIC5tYXAoZiA9PiBwYXRoLnBvc2l4LmpvaW4ocCwgZikpXG4gICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGYgPT4gaXNEaXJlY3RvcnkoZikpO1xuICBzY29wZXMuZm9yRWFjaChmID0+IHBrZ3MucHVzaCguLi5maW5kUGFja2FnZXMoZikpKTtcblxuICBhZGREeW5hbWljRGVwZW5kZW5jaWVzKHBrZ3MpO1xuXG4gIHJldHVybiBwa2dzO1xufVxuXG4vKipcbiAqIEZpbmRzIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGFsbCBwYWNrYWdlIHNjb3BlcyBpbiBub2RlX21vZHVsZXMuXG4gKi9cbmZ1bmN0aW9uIGZpbmRTY29wZXMoKSB7XG4gIGNvbnN0IHAgPSAnbm9kZV9tb2R1bGVzJztcbiAgaWYgKCFpc0RpcmVjdG9yeShwKSkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGxpc3RpbmcgPSBmcy5yZWFkZGlyU3luYyhwKTtcblxuICBjb25zdCBzY29wZXMgPSBsaXN0aW5nLmZpbHRlcihmID0+IGYuc3RhcnRzV2l0aCgnQCcpKVxuICAgICAgICAgICAgICAgICAgICAgLm1hcChmID0+IHBhdGgucG9zaXguam9pbihwLCBmKSlcbiAgICAgICAgICAgICAgICAgICAgIC5maWx0ZXIoZiA9PiBpc0RpcmVjdG9yeShmKSlcbiAgICAgICAgICAgICAgICAgICAgIC5tYXAoZiA9PiBmLnJlcGxhY2UoL15ub2RlX21vZHVsZXNcXC8vLCAnJykpO1xuXG4gIHJldHVybiBzY29wZXM7XG59XG5cbi8qKlxuICogR2l2ZW4gdGhlIG5hbWUgb2YgYSB0b3AtbGV2ZWwgZm9sZGVyIGluIG5vZGVfbW9kdWxlcywgcGFyc2UgdGhlXG4gKiBwYWNrYWdlIGpzb24gYW5kIHJldHVybiBpdCBhcyBhbiBvYmplY3QgYWxvbmcgd2l0aFxuICogc29tZSBhZGRpdGlvbmFsIGludGVybmFsIGF0dHJpYnV0ZXMgcHJlZml4ZWQgd2l0aCAnXycuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGFja2FnZShwOiBzdHJpbmcpOiBEZXAge1xuICAvLyBQYXJzZSB0aGUgcGFja2FnZS5qc29uIGZpbGUgb2YgdGhpcyBwYWNrYWdlXG4gIGNvbnN0IHBhY2thZ2VKc29uID0gcGF0aC5wb3NpeC5qb2luKHAsICdwYWNrYWdlLmpzb24nKTtcbiAgY29uc3QgcGtnID0gaXNGaWxlKHBhY2thZ2VKc29uKSA/IEpTT04ucGFyc2UoZnMucmVhZEZpbGVTeW5jKHBhY2thZ2VKc29uLCB7ZW5jb2Rpbmc6ICd1dGY4J30pKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7dmVyc2lvbjogJzAuMC4wJ307XG5cbiAgLy8gVHJpbSB0aGUgbGVhZGluZyBub2RlX21vZHVsZXMgZnJvbSB0aGUgcGF0aCBhbmRcbiAgLy8gYXNzaWduIHRvIF9kaXIgZm9yIGZ1dHVyZSB1c2VcbiAgcGtnLl9kaXIgPSBwLnJlcGxhY2UoL15ub2RlX21vZHVsZXNcXC8vLCAnJyk7XG5cbiAgLy8gU3Rhc2ggdGhlIHBhY2thZ2UgZGlyZWN0b3J5IG5hbWUgZm9yIGZ1dHVyZSB1c2VcbiAgcGtnLl9uYW1lID0gcGtnLl9kaXIuc3BsaXQoJy8nKS5wb3AoKTtcblxuICAvLyBNb2R1bGUgbmFtZSBvZiB0aGUgcGFja2FnZS4gVW5saWtlIFwiX25hbWVcIiB0aGlzIHJlcHJlc2VudHMgdGhlXG4gIC8vIGZ1bGwgcGFja2FnZSBuYW1lIChpbmNsdWRpbmcgc2NvcGUgbmFtZSkuXG4gIHBrZy5fbW9kdWxlTmFtZSA9IHBrZy5uYW1lIHx8IGAke3BrZy5fZGlyfS8ke3BrZy5fbmFtZX1gO1xuXG4gIC8vIEtlZXAgdHJhY2sgb2Ygd2hldGhlciBvciBub3QgdGhpcyBpcyBhIG5lc3RlZCBwYWNrYWdlXG4gIHBrZy5faXNOZXN0ZWQgPSAvXFwvbm9kZV9tb2R1bGVzXFwvLy50ZXN0KHApO1xuXG4gIC8vIExpc3QgYWxsIHRoZSBmaWxlcyBpbiB0aGUgbnBtIHBhY2thZ2UgZm9yIGxhdGVyIHVzZVxuICBwa2cuX2ZpbGVzID0gbGlzdEZpbGVzKHApO1xuXG4gIC8vIEluaXRpYWxpemUgX2RlcGVuZGVuY2llcyB0byBhbiBlbXB0eSBhcnJheVxuICAvLyB3aGljaCBpcyBsYXRlciBmaWxsZWQgd2l0aCB0aGUgZmxhdHRlbmVkIGRlcGVuZGVuY3kgbGlzdFxuICBwa2cuX2RlcGVuZGVuY2llcyA9IFtdO1xuXG4gIC8vIEhpZGUgYmF6ZWwgZmlsZXMgaW4gdGhpcyBwYWNrYWdlLiBXZSBkbyB0aGlzIGJlZm9yZSBwYXJzaW5nXG4gIC8vIHRoZSBuZXh0IHBhY2thZ2UgdG8gcHJldmVudCBpc3N1ZXMgY2F1c2VkIGJ5IHN5bWxpbmtzIGJldHdlZW5cbiAgLy8gcGFja2FnZSBhbmQgbmVzdGVkIHBhY2thZ2VzIHNldHVwIGJ5IHRoZSBwYWNrYWdlIG1hbmFnZXIuXG4gIGhpZGVCYXplbEZpbGVzKHBrZyk7XG5cbiAgcmV0dXJuIHBrZztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBhIGJpbiBlbnRyeSBpcyBhIG5vbi1lbXB0eSBwYXRoXG4gKi9cbmZ1bmN0aW9uIGlzVmFsaWRCaW5QYXRoKGVudHJ5OiBhbnkpIHtcbiAgcmV0dXJuIGlzVmFsaWRCaW5QYXRoU3RyaW5nVmFsdWUoZW50cnkpIHx8IGlzVmFsaWRCaW5QYXRoT2JqZWN0VmFsdWVzKGVudHJ5KTtcbn1cblxuLyoqXG4gKiBJZiBnaXZlbiBhIHN0cmluZywgY2hlY2sgaWYgYSBiaW4gZW50cnkgaXMgYSBub24tZW1wdHkgcGF0aFxuICovXG5mdW5jdGlvbiBpc1ZhbGlkQmluUGF0aFN0cmluZ1ZhbHVlKGVudHJ5OiBhbnkpIHtcbiAgcmV0dXJuIHR5cGVvZiBlbnRyeSA9PT0gJ3N0cmluZycgJiYgZW50cnkgIT09ICcnO1xufVxuXG4vKipcbiAqIElmIGdpdmVuIGFuIG9iamVjdCBsaXRlcmFsLCBjaGVjayBpZiBhIGJpbiBlbnRyeSBvYmplY3RzIGhhcyBhdCBsZWFzdCBvbmUgYSBub24tZW1wdHkgcGF0aFxuICogRXhhbXBsZSAxOiB7IGVudHJ5OiAnLi9wYXRoL3RvL3NjcmlwdC5qcycgfSA9PT4gVkFMSURcbiAqIEV4YW1wbGUgMjogeyBlbnRyeTogJycgfSA9PT4gSU5WQUxJRFxuICogRXhhbXBsZSAzOiB7IGVudHJ5OiAnLi9wYXRoL3RvL3NjcmlwdC5qcycsIGVtcHR5OiAnJyB9ID09PiBWQUxJRFxuICovXG5mdW5jdGlvbiBpc1ZhbGlkQmluUGF0aE9iamVjdFZhbHVlcyhlbnRyeTogQmFnPHN0cmluZz4pOiBib29sZWFuIHtcbiAgLy8gV2UgYWxsb3cgYXQgbGVhc3Qgb25lIHZhbGlkIGVudHJ5IHBhdGggKGlmIGFueSkuXG4gIHJldHVybiBlbnRyeSAmJiB0eXBlb2YgZW50cnkgPT09ICdvYmplY3QnICYmXG4gICAgICBPYmplY3RbJ3ZhbHVlcyddKGVudHJ5KS5maWx0ZXIoX2VudHJ5ID0+IGlzVmFsaWRCaW5QYXRoKF9lbnRyeSkpLmxlbmd0aCA+IDA7XG59XG5cbi8qKlxuICogQ2xlYW51cCBhIHBhY2thZ2UuanNvbiBcImJpblwiIHBhdGguXG4gKlxuICogQmluIHBhdGhzIHVzdWFsbHkgY29tZSBpbiAyIGZsYXZvcnM6ICcuL2Jpbi9mb28nIG9yICdiaW4vZm9vJyxcbiAqIHNvbWV0aW1lcyBvdGhlciBzdHVmZiBsaWtlICdsaWIvZm9vJy4gIFJlbW92ZSBwcmVmaXggJy4vJyBpZiBpdFxuICogZXhpc3RzLlxuICovXG5mdW5jdGlvbiBjbGVhbnVwQmluUGF0aChwOiBzdHJpbmcpIHtcbiAgcCA9IHAucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuICBpZiAocC5pbmRleE9mKCcuLycpID09PSAwKSB7XG4gICAgcCA9IHAuc2xpY2UoMik7XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbi8qKlxuICogQ2xlYW51cCBhIHBhY2thZ2UuanNvbiBlbnRyeSBwb2ludCBzdWNoIGFzIFwibWFpblwiXG4gKlxuICogUmVtb3ZlcyAnLi8nIGlmIGl0IGV4aXN0cy5cbiAqIEFwcGVuZHMgYGluZGV4LmpzYCBpZiBwIGVuZHMgd2l0aCBgL2AuXG4gKi9cbmZ1bmN0aW9uIGNsZWFudXBFbnRyeVBvaW50UGF0aChwOiBzdHJpbmcpIHtcbiAgcCA9IHAucmVwbGFjZSgvXFxcXC9nLCAnLycpO1xuICBpZiAocC5pbmRleE9mKCcuLycpID09PSAwKSB7XG4gICAgcCA9IHAuc2xpY2UoMik7XG4gIH1cbiAgaWYgKHAuZW5kc1dpdGgoJy8nKSkge1xuICAgIHAgKz0gJ2luZGV4LmpzJztcbiAgfVxuICByZXR1cm4gcDtcbn1cblxuLyoqXG4gKiBDbGVhbnMgdXAgdGhlIGdpdmVuIHBhdGhcbiAqIFRoZW4gdHJpZXMgdG8gcmVzb2x2ZSB0aGUgcGF0aCBpbnRvIGEgZmlsZSBhbmQgd2FybnMgaWYgVkVSQk9TRV9MT0dTIHNldCBhbmQgdGhlIGZpbGUgZG9zZW4ndFxuICogZXhpc3RcbiAqIEBwYXJhbSB7YW55fSBwa2dcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiBmaW5kRW50cnlGaWxlKHBrZzogRGVwLCBwYXRoOiBzdHJpbmcpIHtcbiAgY29uc3QgY2xlYW5QYXRoID0gY2xlYW51cEVudHJ5UG9pbnRQYXRoKHBhdGgpO1xuICAvLyBjaGVjayBpZiBtYWluIGVudHJ5IHBvaW50IGV4aXN0c1xuICBjb25zdCBlbnRyeUZpbGUgPSBmaW5kRmlsZShwa2csIGNsZWFuUGF0aCkgfHwgZmluZEZpbGUocGtnLCBgJHtjbGVhblBhdGh9LmpzYCk7XG4gIGlmICghZW50cnlGaWxlKSB7XG4gICAgLy8gSWYgZW50cnlQb2ludCBlbnRyeSBwb2ludCBsaXN0ZWQgY291bGQgbm90IGJlIHJlc29sdmVkIHRvIGEgZmlsZVxuICAgIC8vIFRoaXMgY2FuIGhhcHBlblxuICAgIC8vIGluIHNvbWUgbnBtIHBhY2thZ2VzIHRoYXQgbGlzdCBhbiBpbmNvcnJlY3QgbWFpbiBzdWNoIGFzIHY4LWNvdmVyYWdlQDEuMC44XG4gICAgLy8gd2hpY2ggbGlzdHMgYFwibWFpblwiOiBcImluZGV4LmpzXCJgIGJ1dCB0aGF0IGZpbGUgZG9lcyBub3QgZXhpc3QuXG4gICAgbG9nX3ZlcmJvc2UoXG4gICAgICAgIGBjb3VsZCBub3QgZmluZCBlbnRyeSBwb2ludCBmb3IgdGhlIHBhdGggJHtjbGVhblBhdGh9IGdpdmVuIGJ5IG5wbSBwYWNrYWdlICR7cGtnLl9uYW1lfWApO1xuICB9XG4gIHJldHVybiBlbnRyeUZpbGU7XG59XG5cbi8qKlxuICogVHJpZXMgdG8gcmVzb2x2ZSB0aGUgZW50cnlQb2ludCBmaWxlIGZyb20gdGhlIHBrZyBmb3IgYSBnaXZlbiBtYWluRmlsZU5hbWVcbiAqXG4gKiBAcGFyYW0ge2FueX0gcGtnXG4gKiBAcGFyYW0geydicm93c2VyJyB8ICdtb2R1bGUnIHwgJ21haW4nfSBtYWluRmlsZU5hbWVcbiAqIEByZXR1cm5zIHtzdHJpbmcgfCB1bmRlZmluZWR9IHRoZSBwYXRoIG9yIHVuZGVmaW5lZCBpZiB3ZSBjYW50IHJlc29sdmUgdGhlIGZpbGVcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZU1haW5GaWxlKHBrZzogRGVwLCBtYWluRmlsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCBtYWluRW50cnlGaWVsZCA9IHBrZ1ttYWluRmlsZU5hbWVdO1xuXG4gIGlmIChtYWluRW50cnlGaWVsZCkge1xuICAgIGlmICh0eXBlb2YgbWFpbkVudHJ5RmllbGQgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gZmluZEVudHJ5RmlsZShwa2csIG1haW5FbnRyeUZpZWxkKVxuXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbWFpbkVudHJ5RmllbGQgPT09ICdvYmplY3QnICYmIG1haW5GaWxlTmFtZSA9PT0gJ2Jyb3dzZXInKSB7XG4gICAgICAvLyBicm93c2VyIGhhcyBhIHdlaXJkIHdheSBvZiBkZWZpbmluZyB0aGlzXG4gICAgICAvLyB0aGUgYnJvd3NlciB2YWx1ZSBpcyBhbiBvYmplY3QgbGlzdGluZyBmaWxlcyB0byBhbGlhcywgdXN1YWxseSBwb2ludGluZyB0byBhIGJyb3dzZXIgZGlyXG4gICAgICBjb25zdCBpbmRleEVudHJ5UG9pbnQgPSBtYWluRW50cnlGaWVsZFsnaW5kZXguanMnXSB8fCBtYWluRW50cnlGaWVsZFsnLi9pbmRleC5qcyddO1xuICAgICAgaWYgKGluZGV4RW50cnlQb2ludCkge1xuICAgICAgICByZXR1cm4gZmluZEVudHJ5RmlsZShwa2csIGluZGV4RW50cnlQb2ludClcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUcmllcyB0byByZXNvbHZlIHRoZSBtYWluRmlsZSBmcm9tIGEgZ2l2ZW4gcGtnXG4gKiBUaGlzIHVzZXMgc2V2ZWFsIG1haW5GaWxlTmFtZXMgaW4gcHJpb3JpdHkgdG8gZmluZCBhIGNvcnJlY3QgdXNhYmxlIGZpbGVcbiAqIEBwYXJhbSB7YW55fSBwa2dcbiAqIEByZXR1cm5zIHtzdHJpbmcgfCB1bmRlZmluZWR9XG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVQa2dNYWluRmlsZShwa2c6IERlcCkge1xuICAvLyBlczIwMTUgaXMgYW5vdGhlciBvcHRpb24gZm9yIG1haW5GaWxlIGhlcmVcbiAgLy8gYnV0IGl0cyB2ZXJ5IHVuY29tbW9uIGFuZCBpbSBub3Qgc3VyZSB3aGF0IHByaW9yaXR5IGl0IHRha2VzXG4gIC8vXG4gIC8vIHRoaXMgbGlzdCBpcyBvcmRlcmVkLCB3ZSB0cnkgcmVzb2x2ZSBgYnJvd3NlcmAgZmlyc3QsIHRoZW4gYG1vZHVsZWAgYW5kIGZpbmFsbHkgZmFsbCBiYWNrIHRvXG4gIC8vIGBtYWluYFxuICBjb25zdCBtYWluRmlsZU5hbWVzID0gWydicm93c2VyJywgJ21vZHVsZScsICdtYWluJ11cblxuICAgICAgZm9yIChjb25zdCBtYWluRmlsZSBvZiBtYWluRmlsZU5hbWVzKSB7XG4gICAgY29uc3QgcmVzb2x2ZWRNYWluRmlsZSA9IHJlc29sdmVNYWluRmlsZShwa2csIG1haW5GaWxlKTtcbiAgICBpZiAocmVzb2x2ZWRNYWluRmlsZSkge1xuICAgICAgcmV0dXJuIHJlc29sdmVkTWFpbkZpbGU7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgd2UgY2FudCBmaW5kIGFueSBjb3JyZWN0IGZpbGUgcmVmZXJlbmNlcyBmcm9tIHRoZSBwa2dcbiAgLy8gdGhlbiB3ZSBqdXN0IHRyeSBsb29raW5nIGFyb3VuZCBmb3IgY29tbW9uIHBhdHRlcm5zXG4gIGNvbnN0IG1heWJlUm9vdEluZGV4ID0gZmluZEVudHJ5RmlsZShwa2csICdpbmRleC5qcycpO1xuICBpZiAobWF5YmVSb290SW5kZXgpIHtcbiAgICByZXR1cm4gbWF5YmVSb290SW5kZXhcbiAgfVxuXG4gIGNvbnN0IG1heWJlU2VsZk5hbWVkSW5kZXggPSBmaW5kRW50cnlGaWxlKHBrZywgYCR7cGtnLl9uYW1lfS5qc2ApO1xuICBpZiAobWF5YmVTZWxmTmFtZWRJbmRleCkge1xuICAgIHJldHVybiBtYXliZVNlbGZOYW1lZEluZGV4O1xuICB9XG5cbiAgLy8gbm9uZSBvZiB0aGUgbWV0aG9kcyB3ZSB0cmllZCByZXN1bHRlZCBpbiBhIGZpbGVcbiAgbG9nX3ZlcmJvc2UoYGNvdWxkIG5vdCBmaW5kIGVudHJ5IHBvaW50IGZvciBucG0gcGFja2FnZSAke3BrZy5fbmFtZX1gKTtcblxuICAvLyBhdCB0aGlzIHBvaW50IHRoZXJlJ3Mgbm90aGluZyBsZWZ0IGZvciB1cyB0byB0cnksIHNvIHJldHVybiBub3RoaW5nXG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbnR5cGUgQmFnPFQ+ID1cbiAgICB7XG4gICAgICBbazogc3RyaW5nXTogVFxuICAgIH1cblxuLyoqXG4gKiBGbGF0dGVucyBhbGwgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMgb2YgYSBwYWNrYWdlXG4gKiBpbnRvIGEgX2RlcGVuZGVuY2llcyBhcnJheS5cbiAqL1xuZnVuY3Rpb24gZmxhdHRlblBrZ0RlcGVuZGVuY2llcyhwa2c6IERlcCwgZGVwOiBEZXAsIHBrZ3NNYXA6IE1hcDxzdHJpbmcsIERlcD4pIHtcbiAgaWYgKHBrZy5fZGVwZW5kZW5jaWVzLmluZGV4T2YoZGVwKSAhPT0gLTEpIHtcbiAgICAvLyBjaXJjdWxhciBkZXBlbmRlbmN5XG4gICAgcmV0dXJuO1xuICB9XG4gIHBrZy5fZGVwZW5kZW5jaWVzLnB1c2goZGVwKTtcbiAgY29uc3QgZmluZERlcHMgPSBmdW5jdGlvbih0YXJnZXREZXBzOiBCYWc8c3RyaW5nPiwgcmVxdWlyZWQ6IGJvb2xlYW4sIGRlcFR5cGU6IHN0cmluZykge1xuICAgIE9iamVjdC5rZXlzKHRhcmdldERlcHMgfHwge30pXG4gICAgICAgIC5tYXAodGFyZ2V0RGVwID0+IHtcbiAgICAgICAgICAvLyBsb29rIGZvciBtYXRjaGluZyBuZXN0ZWQgcGFja2FnZVxuICAgICAgICAgIGNvbnN0IGRpclNlZ21lbnRzID0gZGVwLl9kaXIuc3BsaXQoJy8nKTtcbiAgICAgICAgICB3aGlsZSAoZGlyU2VnbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBjb25zdCBtYXliZSA9IHBhdGgucG9zaXguam9pbiguLi5kaXJTZWdtZW50cywgJ25vZGVfbW9kdWxlcycsIHRhcmdldERlcCk7XG4gICAgICAgICAgICBpZiAocGtnc01hcC5oYXMobWF5YmUpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBwa2dzTWFwLmdldChtYXliZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBkaXJTZWdtZW50cy5wb3AoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gbG9vayBmb3IgbWF0Y2hpbmcgcm9vdCBwYWNrYWdlXG4gICAgICAgICAgaWYgKHBrZ3NNYXAuaGFzKHRhcmdldERlcCkpIHtcbiAgICAgICAgICAgIHJldHVybiBwa2dzTWFwLmdldCh0YXJnZXREZXApO1xuICAgICAgICAgIH1cbiAgICAgICAgICAvLyBkZXBlbmRlbmN5IG5vdCBmb3VuZFxuICAgICAgICAgIGlmIChyZXF1aXJlZCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgY291bGQgbm90IGZpbmQgJHtkZXBUeXBlfSAnJHt0YXJnZXREZXB9JyBvZiAnJHtkZXAuX2Rpcn0nYCk7XG4gICAgICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9KVxuICAgICAgICAuZmlsdGVyKGRlcCA9PiAhIWRlcClcbiAgICAgICAgLmZvckVhY2goZGVwID0+IGZsYXR0ZW5Qa2dEZXBlbmRlbmNpZXMocGtnLCBkZXAhLCBwa2dzTWFwKSk7XG4gIH07XG4gIC8vIG5wbSB3aWxsIGluIHNvbWUgY2FzZXMgYWRkIG9wdGlvbmFsRGVwZW5kZW5jaWVzIHRvIHRoZSBsaXN0XG4gIC8vIG9mIGRlcGVuZGVuY2llcyB0byB0aGUgcGFja2FnZS5qc29uIGl0IHdyaXRlcyB0byBub2RlX21vZHVsZXMuXG4gIC8vIFdlIGRlbGV0ZSB0aGVzZSBoZXJlIGlmIHRoZXkgZXhpc3QgYXMgdGhleSBtYXkgcmVzdWx0XG4gIC8vIGluIGV4cGVjdGVkIGRlcGVuZGVuY2llcyB0aGF0IGFyZSBub3QgZm91bmQuXG4gIGlmIChkZXAuZGVwZW5kZW5jaWVzICYmIGRlcC5vcHRpb25hbERlcGVuZGVuY2llcykge1xuICAgIE9iamVjdC5rZXlzKGRlcC5vcHRpb25hbERlcGVuZGVuY2llcykuZm9yRWFjaChvcHRpb25hbERlcCA9PiB7XG4gICAgICBkZWxldGUgZGVwLmRlcGVuZGVuY2llc1tvcHRpb25hbERlcF07XG4gICAgfSk7XG4gIH1cblxuICBmaW5kRGVwcyhkZXAuZGVwZW5kZW5jaWVzLCB0cnVlLCAnZGVwZW5kZW5jeScpO1xuICBmaW5kRGVwcyhkZXAucGVlckRlcGVuZGVuY2llcywgdHJ1ZSwgJ3BlZXIgZGVwZW5kZW5jeScpO1xuICAvLyBgb3B0aW9uYWxEZXBlbmRlbmNpZXNgIHRoYXQgYXJlIG1pc3Npbmcgc2hvdWxkIGJlIHNpbGVudGx5XG4gIC8vIGlnbm9yZWQgc2luY2UgdGhlIG5wbS95YXJuIHdpbGwgbm90IGZhaWwgaWYgdGhlc2UgZGVwZW5kZW5jaWVzXG4gIC8vIGZhaWwgdG8gaW5zdGFsbC4gUGFja2FnZXMgc2hvdWxkIGhhbmRsZSB0aGUgY2FzZXMgd2hlcmUgdGhlc2VcbiAgLy8gZGVwZW5kZW5jaWVzIGFyZSBtaXNzaW5nIGdyYWNlZnVsbHkgYXQgcnVudGltZS5cbiAgLy8gQW4gZXhhbXBsZSBvZiB0aGlzIGlzIHRoZSBgY2hva2lkYXJgIHBhY2thZ2Ugd2hpY2ggc3BlY2lmaWVzXG4gIC8vIGBmc2V2ZW50c2AgYXMgYW4gb3B0aW9uYWxEZXBlbmRlbmN5LiBPbiBPU1gsIGBmc2V2ZW50c2BcbiAgLy8gaXMgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseSwgYnV0IG9uIFdpbmRvd3MgJiBMaW51eCwgYGZzZXZlbnRzYFxuICAvLyBmYWlscyB0byBpbnN0YWxsIGFuZCB0aGUgcGFja2FnZSB3aWxsIG5vdCBiZSBwcmVzZW50IHdoZW5cbiAgLy8gY2hlY2tpbmcgdGhlIGRlcGVuZGVuY2llcyBvZiBgY2hva2lkYXJgLlxuICBmaW5kRGVwcyhkZXAub3B0aW9uYWxEZXBlbmRlbmNpZXMsIGZhbHNlLCAnb3B0aW9uYWwgZGVwZW5kZW5jeScpO1xufVxuXG4vKipcbiAqIFJlZm9ybWF0L3ByZXR0eS1wcmludCBhIGpzb24gb2JqZWN0IGFzIGEgc2t5bGFyayBjb21tZW50IChlYWNoIGxpbmVcbiAqIHN0YXJ0cyB3aXRoICcjICcpLlxuICovXG5mdW5jdGlvbiBwcmludEpzb24ocGtnOiBEZXApIHtcbiAgLy8gQ2xvbmUgYW5kIG1vZGlmeSBfZGVwZW5kZW5jaWVzIHRvIGF2b2lkIGNpcmN1bGFyIGlzc3VlcyB3aGVuIEpTT05pZnlpbmdcbiAgLy8gJiBkZWxldGUgX2ZpbGVzIGFycmF5XG4gIGNvbnN0IGNsb25lZDogYW55ID0gey4uLnBrZ307XG4gIGNsb25lZC5fZGVwZW5kZW5jaWVzID0gcGtnLl9kZXBlbmRlbmNpZXMubWFwKGRlcCA9PiBkZXAuX2Rpcik7XG4gIGRlbGV0ZSBjbG9uZWQuX2ZpbGVzO1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoY2xvbmVkLCBudWxsLCAyKS5zcGxpdCgnXFxuJykubWFwKGxpbmUgPT4gYCMgJHtsaW5lfWApLmpvaW4oJ1xcbicpO1xufVxuXG4vKipcbiAqIEEgZmlsdGVyIGZ1bmN0aW9uIGZvciBmaWxlcyBpbiBhbiBucG0gcGFja2FnZS4gQ29tcGFyaXNvbiBpcyBjYXNlLWluc2Vuc2l0aXZlLlxuICogQHBhcmFtIGZpbGVzIGFycmF5IG9mIGZpbGVzIHRvIGZpbHRlclxuICogQHBhcmFtIGV4dHMgbGlzdCBvZiB3aGl0ZSBsaXN0ZWQgY2FzZS1pbnNlbnNpdGl2ZSBleHRlbnNpb25zOyBpZiBlbXB0eSwgbm8gZmlsdGVyIGlzXG4gKiAgICAgICAgICAgICBkb25lIG9uIGV4dGVuc2lvbnM7ICcnIGVtcHR5IHN0cmluZyBkZW5vdGVzIHRvIGFsbG93IGZpbGVzIHdpdGggbm8gZXh0ZW5zaW9ucyxcbiAqICAgICAgICAgICAgIG90aGVyIGV4dGVuc2lvbnMgYXJlIGxpc3RlZCB3aXRoICcuZXh0JyBub3RhdGlvbiBzdWNoIGFzICcuZC50cycuXG4gKi9cbmZ1bmN0aW9uIGZpbHRlckZpbGVzKGZpbGVzOiBzdHJpbmdbXSwgZXh0czogc3RyaW5nW10gPSBbXSkge1xuICBpZiAoZXh0cy5sZW5ndGgpIHtcbiAgICBjb25zdCBhbGxvd05vRXh0cyA9IGV4dHMuaW5jbHVkZXMoJycpO1xuICAgIGZpbGVzID0gZmlsZXMuZmlsdGVyKGYgPT4ge1xuICAgICAgLy8gaW5jbHVkZSBmaWxlcyB3aXRoIG5vIGV4dGVuc2lvbnMgaWYgbm9FeHQgaXMgdHJ1ZVxuICAgICAgaWYgKGFsbG93Tm9FeHRzICYmICFwYXRoLmV4dG5hbWUoZikpIHJldHVybiB0cnVlO1xuICAgICAgLy8gZmlsdGVyIGZpbGVzIGluIGV4dHNcbiAgICAgIGNvbnN0IGxjID0gZi50b0xvd2VyQ2FzZSgpO1xuICAgICAgZm9yIChjb25zdCBlIG9mIGV4dHMpIHtcbiAgICAgICAgaWYgKGUgJiYgbGMuZW5kc1dpdGgoZS50b0xvd2VyQ2FzZSgpKSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfSlcbiAgfVxuICAvLyBGaWx0ZXIgb3V0IEJVSUxEIGZpbGVzIHRoYXQgY2FtZSB3aXRoIHRoZSBucG0gcGFja2FnZVxuICByZXR1cm4gZmlsZXMuZmlsdGVyKGZpbGUgPT4ge1xuICAgIGNvbnN0IGJhc2VuYW1lVWMgPSBwYXRoLmJhc2VuYW1lKGZpbGUpLnRvVXBwZXJDYXNlKCk7XG4gICAgaWYgKGJhc2VuYW1lVWMgPT09ICdfQlVJTEQnIHx8IGJhc2VuYW1lVWMgPT09ICdfQlVJTEQuQkFaRUwnKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIHRydWUgaWYgdGhlIHNwZWNpZmllZCBgcGtnYCBjb25mb3JtcyB0byBBbmd1bGFyIFBhY2thZ2UgRm9ybWF0IChBUEYpLFxuICogZmFsc2Ugb3RoZXJ3aXNlLiBJZiB0aGUgcGFja2FnZSBjb250YWlucyBgKi5tZXRhZGF0YS5qc29uYCBhbmQgYVxuICogY29ycmVzcG9uZGluZyBzaWJsaW5nIGAuZC50c2AgZmlsZSwgdGhlbiB0aGUgcGFja2FnZSBpcyBjb25zaWRlcmVkIHRvIGJlIEFQRi5cbiAqL1xuZnVuY3Rpb24gaXNOZ0FwZlBhY2thZ2UocGtnOiBEZXApIHtcbiAgY29uc3Qgc2V0ID0gbmV3IFNldChwa2cuX2ZpbGVzKTtcbiAgaWYgKHNldC5oYXMoJ0FOR1VMQVJfUEFDS0FHRScpKSB7XG4gICAgLy8gVGhpcyBmaWxlIGlzIHVzZWQgYnkgdGhlIG5wbS95YXJuX2luc3RhbGwgcnVsZSB0byBkZXRlY3QgQVBGLiBTZWVcbiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9ydWxlc19ub2RlanMvaXNzdWVzLzkyN1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGNvbnN0IG1ldGFkYXRhRXh0ID0gL1xcLm1ldGFkYXRhXFwuanNvbiQvO1xuICByZXR1cm4gcGtnLl9maWxlcy5zb21lKChmaWxlKSA9PiB7XG4gICAgaWYgKG1ldGFkYXRhRXh0LnRlc3QoZmlsZSkpIHtcbiAgICAgIGNvbnN0IHNpYmxpbmcgPSBmaWxlLnJlcGxhY2UobWV0YWRhdGFFeHQsICcuZC50cycpO1xuICAgICAgaWYgKHNldC5oYXMoc2libGluZykpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSk7XG59XG5cbi8qKlxuICogSWYgdGhlIHBhY2thZ2UgaXMgaW4gdGhlIEFuZ3VsYXIgcGFja2FnZSBmb3JtYXQgcmV0dXJucyBsaXN0XG4gKiBvZiBwYWNrYWdlIGZpbGVzIHRoYXQgZW5kIHdpdGggYC51bWQuanNgLCBgLm5nZmFjdG9yeS5qc2AgYW5kIGAubmdzdW1tYXJ5LmpzYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmdBcGZTY3JpcHRzKHBrZzogRGVwKSB7XG4gIHJldHVybiBpc05nQXBmUGFja2FnZShwa2cpID9cbiAgICAgIGZpbHRlckZpbGVzKHBrZy5fZmlsZXMsIFsnLnVtZC5qcycsICcubmdmYWN0b3J5LmpzJywgJy5uZ3N1bW1hcnkuanMnXSkgOlxuICAgICAgW107XG59XG5cbi8qKlxuICogTG9va3MgZm9yIGEgZmlsZSB3aXRoaW4gYSBwYWNrYWdlIGFuZCByZXR1cm5zIGl0IGlmIGZvdW5kLlxuICovXG5mdW5jdGlvbiBmaW5kRmlsZShwa2c6IERlcCwgbTogc3RyaW5nKSB7XG4gIGNvbnN0IG1sID0gbS50b0xvd2VyQ2FzZSgpO1xuICBmb3IgKGNvbnN0IGYgb2YgcGtnLl9maWxlcykge1xuICAgIGlmIChmLnRvTG93ZXJDYXNlKCkgPT09IG1sKSB7XG4gICAgICByZXR1cm4gZjtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBHaXZlbiBhIHBrZywgcmV0dXJuIHRoZSBza3lsYXJrIGBub2RlX21vZHVsZV9saWJyYXJ5YCB0YXJnZXRzIGZvciB0aGUgcGFja2FnZS5cbiAqL1xuZnVuY3Rpb24gcHJpbnRQYWNrYWdlKHBrZzogRGVwKSB7XG4gIGNvbnN0IHNvdXJjZXMgPSBmaWx0ZXJGaWxlcyhwa2cuX2ZpbGVzLCBJTkNMVURFRF9GSUxFUyk7XG4gIGNvbnN0IGR0c1NvdXJjZXMgPSBmaWx0ZXJGaWxlcyhwa2cuX2ZpbGVzLCBbJy5kLnRzJ10pO1xuICAvLyBUT0RPKGdtYWdvbGFuKTogYWRkIFVNRCAmIEFNRCBzY3JpcHRzIHRvIHNjcmlwdHMgZXZlbiBpZiBub3QgYW4gQVBGIHBhY2thZ2UgX2J1dF8gb25seSBpZiB0aGV5XG4gIC8vIGFyZSBuYW1lZD9cbiAgY29uc3Qgc2NyaXB0cyA9IGdldE5nQXBmU2NyaXB0cyhwa2cpO1xuICBjb25zdCBkZXBzID0gW3BrZ10uY29uY2F0KHBrZy5fZGVwZW5kZW5jaWVzLmZpbHRlcihkZXAgPT4gZGVwICE9PSBwa2cgJiYgIWRlcC5faXNOZXN0ZWQpKTtcblxuICBsZXQgc2NyaXB0U3RhcmxhcmsgPSAnJztcbiAgaWYgKHNjcmlwdHMubGVuZ3RoKSB7XG4gICAgc2NyaXB0U3RhcmxhcmsgPSBgXG4gICAgIyBzdWJzZXQgb2Ygc3JjcyB0aGF0IGFyZSBqYXZhc2NyaXB0IG5hbWVkLVVNRCBvciBuYW1lZC1BTUQgc2NyaXB0c1xuICAgIHNjcmlwdHMgPSBbXG4gICAgICAgICR7c2NyaXB0cy5tYXAoKGY6IHN0cmluZykgPT4gYFwiLy86bm9kZV9tb2R1bGVzLyR7cGtnLl9kaXJ9LyR7Zn1cIixgKS5qb2luKCdcXG4gICAgICAgICcpfVxuICAgIF0sYDtcbiAgfVxuXG4gIGxldCBzcmNzU3RhcmxhcmsgPSAnJztcbiAgaWYgKHNvdXJjZXMubGVuZ3RoKSB7XG4gICAgc3Jjc1N0YXJsYXJrID0gYFxuICAgICMgJHtwa2cuX2Rpcn0gcGFja2FnZSBmaWxlcyAoYW5kIGZpbGVzIGluIG5lc3RlZCBub2RlX21vZHVsZXMpXG4gICAgc3JjcyA9IFtcbiAgICAgICAgJHtzb3VyY2VzLm1hcCgoZjogc3RyaW5nKSA9PiBgXCIvLzpub2RlX21vZHVsZXMvJHtwa2cuX2Rpcn0vJHtmfVwiLGApLmpvaW4oJ1xcbiAgICAgICAgJyl9XG4gICAgXSxgO1xuICB9XG5cbiAgbGV0IGRlcHNTdGFybGFyayA9ICcnO1xuICBpZiAoZGVwcy5sZW5ndGgpIHtcbiAgICBjb25zdCBsaXN0ID0gZGVwcy5tYXAoZGVwID0+IGBcIi8vJHtkZXAuX2Rpcn06JHtkZXAuX25hbWV9X19jb250ZW50c1wiLGApLmpvaW4oJ1xcbiAgICAgICAgJyk7XG4gICAgZGVwc1N0YXJsYXJrID0gYFxuICAgICMgZmxhdHRlbmVkIGxpc3Qgb2YgZGlyZWN0IGFuZCB0cmFuc2l0aXZlIGRlcGVuZGVuY2llcyBob2lzdGVkIHRvIHJvb3QgYnkgdGhlIHBhY2thZ2UgbWFuYWdlclxuICAgIGRlcHMgPSBbXG4gICAgICAgICR7bGlzdH1cbiAgICBdLGA7XG4gIH1cblxuICBsZXQgZHRzU3RhcmxhcmsgPSAnJztcbiAgaWYgKGR0c1NvdXJjZXMubGVuZ3RoKSB7XG4gICAgZHRzU3RhcmxhcmsgPSBgXG4gICAgIyAke3BrZy5fZGlyfSBwYWNrYWdlIGRlY2xhcmF0aW9uIGZpbGVzIChhbmQgZGVjbGFyYXRpb24gZmlsZXMgaW4gbmVzdGVkIG5vZGVfbW9kdWxlcylcbiAgICBzcmNzID0gW1xuICAgICAgICAke2R0c1NvdXJjZXMubWFwKGYgPT4gYFwiLy86bm9kZV9tb2R1bGVzLyR7cGtnLl9kaXJ9LyR7Zn1cIixgKS5qb2luKCdcXG4gICAgICAgICcpfVxuICAgIF0sYDtcbiAgfVxuXG4gIGxldCByZXN1bHQgPVxuICAgICAgYGxvYWQoXCJAYnVpbGRfYmF6ZWxfcnVsZXNfbm9kZWpzLy9pbnRlcm5hbC9ucG1faW5zdGFsbDpub2RlX21vZHVsZV9saWJyYXJ5LmJ6bFwiLCBcIm5vZGVfbW9kdWxlX2xpYnJhcnlcIilcblxuIyBHZW5lcmF0ZWQgdGFyZ2V0cyBmb3IgbnBtIHBhY2thZ2UgXCIke3BrZy5fZGlyfVwiXG4ke3ByaW50SnNvbihwa2cpfVxuXG5maWxlZ3JvdXAoXG4gICAgbmFtZSA9IFwiJHtwa2cuX25hbWV9X19maWxlc1wiLCR7c3Jjc1N0YXJsYXJrfVxuKVxuXG5ub2RlX21vZHVsZV9saWJyYXJ5KFxuICAgIG5hbWUgPSBcIiR7cGtnLl9uYW1lfVwiLFxuICAgICMgZGlyZWN0IHNvdXJjZXMgbGlzdGVkIGZvciBzdHJpY3QgZGVwcyBzdXBwb3J0XG4gICAgc3JjcyA9IFtcIjoke3BrZy5fbmFtZX1fX2ZpbGVzXCJdLCR7ZGVwc1N0YXJsYXJrfVxuKVxuXG4jICR7cGtnLl9uYW1lfV9fY29udGVudHMgdGFyZ2V0IGlzIHVzZWQgYXMgZGVwIGZvciBtYWluIHRhcmdldHMgdG8gcHJldmVudFxuIyBjaXJjdWxhciBkZXBlbmRlbmNpZXMgZXJyb3JzXG5ub2RlX21vZHVsZV9saWJyYXJ5KFxuICAgIG5hbWUgPSBcIiR7cGtnLl9uYW1lfV9fY29udGVudHNcIixcbiAgICBzcmNzID0gW1wiOiR7cGtnLl9uYW1lfV9fZmlsZXNcIl0sJHtzY3JpcHRTdGFybGFya31cbilcblxuIyAke3BrZy5fbmFtZX1fX3R5cGluZ3MgaXMgdGhlIHN1YnNldCBvZiAke3BrZy5fbmFtZX1fX2NvbnRlbnRzIHRoYXQgYXJlIGRlY2xhcmF0aW9uc1xubm9kZV9tb2R1bGVfbGlicmFyeShcbiAgICBuYW1lID0gXCIke3BrZy5fbmFtZX1fX3R5cGluZ3NcIiwke2R0c1N0YXJsYXJrfVxuKVxuXG5gO1xuXG4gIGxldCBtYWluRW50cnlQb2ludCA9IHJlc29sdmVQa2dNYWluRmlsZShwa2cpXG5cbiAgLy8gYWRkIGFuIGBucG1fdW1kX2J1bmRsZWAgdGFyZ2V0IHRvIGdlbmVyYXRlIGFuIFVNRCBidW5kbGUgaWYgb25lIGRvZXNcbiAgLy8gbm90IGV4aXN0c1xuICBpZiAobWFpbkVudHJ5UG9pbnQgJiYgIWZpbmRGaWxlKHBrZywgYCR7cGtnLl9uYW1lfS51bWQuanNgKSkge1xuICAgIHJlc3VsdCArPVxuICAgICAgICBgbG9hZChcIkBidWlsZF9iYXplbF9ydWxlc19ub2RlanMvL2ludGVybmFsL25wbV9pbnN0YWxsOm5wbV91bWRfYnVuZGxlLmJ6bFwiLCBcIm5wbV91bWRfYnVuZGxlXCIpXG5cbm5wbV91bWRfYnVuZGxlKFxuICAgIG5hbWUgPSBcIiR7cGtnLl9uYW1lfV9fdW1kXCIsXG4gICAgcGFja2FnZV9uYW1lID0gXCIke3BrZy5fbmFtZX1cIixcbiAgICBlbnRyeV9wb2ludCA9IFwiLy86bm9kZV9tb2R1bGVzLyR7cGtnLl9kaXJ9LyR7bWFpbkVudHJ5UG9pbnR9XCIsXG4gICAgcGFja2FnZSA9IFwiOiR7cGtnLl9uYW1lfVwiLFxuKVxuXG5gO1xuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuZnVuY3Rpb24gX2ZpbmRFeGVjdXRhYmxlcyhwa2c6IERlcCkge1xuICBjb25zdCBleGVjdXRhYmxlcyA9IG5ldyBNYXAoKTtcblxuICAvLyBGb3Igcm9vdCBwYWNrYWdlcywgdHJhbnNmb3JtIHRoZSBwa2cuYmluIGVudHJpZXNcbiAgLy8gaW50byBhIG5ldyBNYXAgY2FsbGVkIF9leGVjdXRhYmxlc1xuICAvLyBOT1RFOiB3ZSBkbyB0aGlzIG9ubHkgZm9yIG5vbi1lbXB0eSBiaW4gcGF0aHNcbiAgaWYgKGlzVmFsaWRCaW5QYXRoKHBrZy5iaW4pKSB7XG4gICAgaWYgKCFwa2cuX2lzTmVzdGVkKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShwa2cuYmluKSkge1xuICAgICAgICBpZiAocGtnLmJpbi5sZW5ndGggPT0gMSkge1xuICAgICAgICAgIGV4ZWN1dGFibGVzLnNldChwa2cuX2RpciwgY2xlYW51cEJpblBhdGgocGtnLmJpblswXSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIHNob3VsZCBub3QgaGFwcGVuLCBidXQgaWdub3JlIGl0IGlmIHByZXNlbnRcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgcGtnLmJpbiA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgZXhlY3V0YWJsZXMuc2V0KHBrZy5fZGlyLCBjbGVhbnVwQmluUGF0aChwa2cuYmluKSk7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBwa2cuYmluID09PSAnb2JqZWN0Jykge1xuICAgICAgICBmb3IgKGxldCBrZXkgaW4gcGtnLmJpbikge1xuICAgICAgICAgIGlmIChpc1ZhbGlkQmluUGF0aFN0cmluZ1ZhbHVlKHBrZy5iaW5ba2V5XSkpIHtcbiAgICAgICAgICAgIGV4ZWN1dGFibGVzLnNldChrZXksIGNsZWFudXBCaW5QYXRoKHBrZy5iaW5ba2V5XSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleGVjdXRhYmxlcztcbn1cblxuLy8gSGFuZGxlIGFkZGl0aW9uYWxBdHRyaWJ1dGVzIG9mIGZvcm1hdDpcbi8vIGBgYFxuLy8gXCJiYXplbEJpblwiOiB7XG4vLyAgIFwibmdjLXdyYXBwZWRcIjoge1xuLy8gICAgIFwiYWRkaXRpb25hbEF0dHJpYnV0ZXNcIjoge1xuLy8gICAgICAgXCJjb25maWd1cmF0aW9uX2Vudl92YXJzXCI6IFwiW1xcXCJjb21waWxlXFxcIl1cIlxuLy8gICB9XG4vLyB9LFxuLy8gYGBgXG5mdW5jdGlvbiBhZGRpdGlvbmFsQXR0cmlidXRlcyhwa2c6IERlcCwgbmFtZTogc3RyaW5nKSB7XG4gIGxldCBhZGRpdGlvbmFsQXR0cmlidXRlcyA9ICcnO1xuICBpZiAocGtnLmJhemVsQmluICYmIHBrZy5iYXplbEJpbltuYW1lXSAmJiBwa2cuYmF6ZWxCaW5bbmFtZV0uYWRkaXRpb25hbEF0dHJpYnV0ZXMpIHtcbiAgICBjb25zdCBhdHRycyA9IHBrZy5iYXplbEJpbltuYW1lXS5hZGRpdGlvbmFsQXR0cmlidXRlcztcbiAgICBmb3IgKGNvbnN0IGF0dHJOYW1lIG9mIE9iamVjdC5rZXlzKGF0dHJzKSkge1xuICAgICAgY29uc3QgYXR0clZhbHVlID0gYXR0cnNbYXR0ck5hbWVdO1xuICAgICAgYWRkaXRpb25hbEF0dHJpYnV0ZXMgKz0gYFxcbiAgICAke2F0dHJOYW1lfSA9ICR7YXR0clZhbHVlfSxgO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYWRkaXRpb25hbEF0dHJpYnV0ZXM7XG59XG5cbi8qKlxuICogR2l2ZW4gYSBwa2csIHJldHVybiB0aGUgc2t5bGFyayBub2RlanNfYmluYXJ5IHRhcmdldHMgZm9yIHRoZSBwYWNrYWdlLlxuICovXG5mdW5jdGlvbiBwcmludFBhY2thZ2VCaW4ocGtnOiBEZXApIHtcbiAgbGV0IHJlc3VsdCA9ICcnO1xuICBjb25zdCBleGVjdXRhYmxlcyA9IF9maW5kRXhlY3V0YWJsZXMocGtnKTtcbiAgaWYgKGV4ZWN1dGFibGVzLnNpemUpIHtcbiAgICByZXN1bHQgPSBgbG9hZChcIkBidWlsZF9iYXplbF9ydWxlc19ub2RlanMvLzppbmRleC5iemxcIiwgXCJub2RlanNfYmluYXJ5XCIpXG5cbmA7XG4gICAgY29uc3QgZGF0YSA9IFtgLy8ke3BrZy5fZGlyfToke3BrZy5fbmFtZX1gXTtcbiAgICBpZiAocGtnLl9keW5hbWljRGVwZW5kZW5jaWVzKSB7XG4gICAgICBkYXRhLnB1c2goLi4ucGtnLl9keW5hbWljRGVwZW5kZW5jaWVzKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBwYXRoXSBvZiBleGVjdXRhYmxlcy5lbnRyaWVzKCkpIHtcbiAgICAgIHJlc3VsdCArPSBgIyBXaXJlIHVwIHRoZSBcXGBiaW5cXGAgZW50cnkgXFxgJHtuYW1lfVxcYFxubm9kZWpzX2JpbmFyeShcbiAgICBuYW1lID0gXCIke25hbWV9XCIsXG4gICAgZW50cnlfcG9pbnQgPSBcIi8vOm5vZGVfbW9kdWxlcy8ke3BrZy5fZGlyfS8ke3BhdGh9XCIsXG4gICAgaW5zdGFsbF9zb3VyY2VfbWFwX3N1cHBvcnQgPSBGYWxzZSxcbiAgICBkYXRhID0gWyR7ZGF0YS5tYXAocCA9PiBgXCIke3B9XCJgKS5qb2luKCcsICcpfV0sJHthZGRpdGlvbmFsQXR0cmlidXRlcyhwa2csIG5hbWUpfVxuKVxuXG5gO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIHByaW50SW5kZXhCemwocGtnOiBEZXApIHtcbiAgbGV0IHJlc3VsdCA9ICcnO1xuICBjb25zdCBleGVjdXRhYmxlcyA9IF9maW5kRXhlY3V0YWJsZXMocGtnKTtcbiAgaWYgKGV4ZWN1dGFibGVzLnNpemUpIHtcbiAgICByZXN1bHQgPSBgbG9hZChcIkBidWlsZF9iYXplbF9ydWxlc19ub2RlanMvLzppbmRleC5iemxcIiwgXCJub2RlanNfYmluYXJ5XCIsIFwibnBtX3BhY2thZ2VfYmluXCIpXG5cbmA7XG4gICAgY29uc3QgZGF0YSA9IFtgQCR7V09SS1NQQUNFfS8vJHtwa2cuX2Rpcn06JHtwa2cuX25hbWV9YF07XG4gICAgaWYgKHBrZy5fZHluYW1pY0RlcGVuZGVuY2llcykge1xuICAgICAgZGF0YS5wdXNoKC4uLnBrZy5fZHluYW1pY0RlcGVuZGVuY2llcyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbbmFtZSwgcGF0aF0gb2YgZXhlY3V0YWJsZXMuZW50cmllcygpKSB7XG4gICAgICByZXN1bHQgPSBgJHtyZXN1bHR9XG5cbiMgR2VuZXJhdGVkIGhlbHBlciBtYWNybyB0byBjYWxsICR7bmFtZX1cbmRlZiAke25hbWUucmVwbGFjZSgvLS9nLCAnXycpfSgqKmt3YXJncyk6XG4gICAgb3V0cHV0X2RpciA9IGt3YXJncy5wb3AoXCJvdXRwdXRfZGlyXCIsIEZhbHNlKVxuICAgIGlmIFwib3V0c1wiIGluIGt3YXJncyBvciBvdXRwdXRfZGlyOlxuICAgICAgICBucG1fcGFja2FnZV9iaW4odG9vbCA9IFwiQCR7V09SS1NQQUNFfS8vJHtwa2cuX2Rpcn0vYmluOiR7XG4gICAgICAgICAgbmFtZX1cIiwgb3V0cHV0X2RpciA9IG91dHB1dF9kaXIsICoqa3dhcmdzKVxuICAgIGVsc2U6XG4gICAgICAgIG5vZGVqc19iaW5hcnkoXG4gICAgICAgICAgICBlbnRyeV9wb2ludCA9IFwiQCR7V09SS1NQQUNFfS8vOm5vZGVfbW9kdWxlcy8ke3BrZy5fZGlyfS8ke3BhdGh9XCIsXG4gICAgICAgICAgICBpbnN0YWxsX3NvdXJjZV9tYXBfc3VwcG9ydCA9IEZhbHNlLFxuICAgICAgICAgICAgZGF0YSA9IFske2RhdGEubWFwKHAgPT4gYFwiJHtwfVwiYCkuam9pbignLCAnKX1dICsga3dhcmdzLnBvcChcImRhdGFcIiwgW10pLCR7XG4gICAgICAgICAgYWRkaXRpb25hbEF0dHJpYnV0ZXMocGtnLCBuYW1lKX1cbiAgICAgICAgICAgICoqa3dhcmdzXG4gICAgICAgIClcbiAgYDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxudHlwZSBEZXAgPSB7XG4gIF9kaXI6IHN0cmluZyxcbiAgX2lzTmVzdGVkOiBib29sZWFuLFxuICBfZGVwZW5kZW5jaWVzOiBEZXBbXSxcbiAgX2ZpbGVzOiBzdHJpbmdbXSxcbiAgW2s6IHN0cmluZ106IGFueVxufVxuXG4vKipcbiAqIEdpdmVuIGEgc2NvcGUsIHJldHVybiB0aGUgc2t5bGFyayBgbm9kZV9tb2R1bGVfbGlicmFyeWAgdGFyZ2V0IGZvciB0aGUgc2NvcGUuXG4gKi9cbmZ1bmN0aW9uIHByaW50U2NvcGUoc2NvcGU6IHN0cmluZywgcGtnczogRGVwW10pIHtcbiAgcGtncyA9IHBrZ3MuZmlsdGVyKHBrZyA9PiAhcGtnLl9pc05lc3RlZCAmJiBwa2cuX2Rpci5zdGFydHNXaXRoKGAke3Njb3BlfS9gKSk7XG4gIGxldCBkZXBzOiBEZXBbXSA9IFtdO1xuICBwa2dzLmZvckVhY2gocGtnID0+IHtcbiAgICBkZXBzID0gZGVwcy5jb25jYXQocGtnLl9kZXBlbmRlbmNpZXMuZmlsdGVyKGRlcCA9PiAhZGVwLl9pc05lc3RlZCAmJiAhcGtncy5pbmNsdWRlcyhwa2cpKSk7XG4gIH0pO1xuICAvLyBmaWx0ZXIgb3V0IGR1cGxpY2F0ZSBkZXBzXG4gIGRlcHMgPSBbLi4ucGtncywgLi4ubmV3IFNldChkZXBzKV07XG5cbiAgbGV0IHNyY3NTdGFybGFyayA9ICcnO1xuICBpZiAoZGVwcy5sZW5ndGgpIHtcbiAgICBjb25zdCBsaXN0ID0gZGVwcy5tYXAoZGVwID0+IGBcIi8vJHtkZXAuX2Rpcn06JHtkZXAuX25hbWV9X19maWxlc1wiLGApLmpvaW4oJ1xcbiAgICAgICAgJyk7XG4gICAgc3Jjc1N0YXJsYXJrID0gYFxuICAgICMgZGlyZWN0IHNvdXJjZXMgbGlzdGVkIGZvciBzdHJpY3QgZGVwcyBzdXBwb3J0XG4gICAgc3JjcyA9IFtcbiAgICAgICAgJHtsaXN0fVxuICAgIF0sYDtcbiAgfVxuXG4gIGxldCBkZXBzU3RhcmxhcmsgPSAnJztcbiAgaWYgKGRlcHMubGVuZ3RoKSB7XG4gICAgY29uc3QgbGlzdCA9IGRlcHMubWFwKGRlcCA9PiBgXCIvLyR7ZGVwLl9kaXJ9OiR7ZGVwLl9uYW1lfV9fY29udGVudHNcIixgKS5qb2luKCdcXG4gICAgICAgICcpO1xuICAgIGRlcHNTdGFybGFyayA9IGBcbiAgICAjIGZsYXR0ZW5lZCBsaXN0IG9mIGRpcmVjdCBhbmQgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMgaG9pc3RlZCB0byByb290IGJ5IHRoZSBwYWNrYWdlIG1hbmFnZXJcbiAgICBkZXBzID0gW1xuICAgICAgICAke2xpc3R9XG4gICAgXSxgO1xuICB9XG5cbiAgcmV0dXJuIGBsb2FkKFwiQGJ1aWxkX2JhemVsX3J1bGVzX25vZGVqcy8vaW50ZXJuYWwvbnBtX2luc3RhbGw6bm9kZV9tb2R1bGVfbGlicmFyeS5iemxcIiwgXCJub2RlX21vZHVsZV9saWJyYXJ5XCIpXG5cbiMgR2VuZXJhdGVkIHRhcmdldCBmb3IgbnBtIHNjb3BlICR7c2NvcGV9XG5ub2RlX21vZHVsZV9saWJyYXJ5KFxuICAgIG5hbWUgPSBcIiR7c2NvcGV9XCIsJHtzcmNzU3Rhcmxhcmt9JHtkZXBzU3Rhcmxhcmt9XG4pXG5cbmA7XG59XG4iXX0= \ No newline at end of file +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2VuZXJhdGVfYnVpbGRfZmlsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL2ludGVybmFsL25wbV9pbnN0YWxsL2dlbmVyYXRlX2J1aWxkX2ZpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7O0lBQUE7Ozs7Ozs7Ozs7Ozs7OztPQWVHO0lBQ0g7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FzQkc7SUFDSCxZQUFZLENBQUM7O0lBR2IseUJBQXlCO0lBQ3pCLDZCQUE2QjtJQUU3QixTQUFTLFdBQVcsQ0FBQyxHQUFHLENBQVE7UUFDOUIsSUFBSSxDQUFDLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7WUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLDBCQUEwQixFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVELE1BQU0saUJBQWlCLEdBQUc7Ozs7OztDQU16QixDQUFBO0lBRUQsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkMsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMxQixNQUFNLG9CQUFvQixHQUFHLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDekQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxD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QUksRUFBRSxHQUFHLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFFbkMsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFDO1FBQ3RCLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLEtBQUssV0FBVyxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3hGLFlBQVksR0FBRzs7O1VBR1QsSUFBSTtPQUNQLENBQUM7U0FDTDtRQUVELElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN0QixJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUU7WUFDZixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxLQUFLLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztZQUMzRixZQUFZLEdBQUc7OztVQUdULElBQUk7T0FDUCxDQUFDO1NBQ0w7UUFFRCxPQUFPOzttQ0FFMEIsS0FBSzs7Y0FFMUIsS0FBSyxLQUFLLFlBQVksR0FBRyxZQUFZOzs7Q0FHbEQsQ0FBQztJQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxNyBUaGUgQmF6ZWwgQXV0aG9ycy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgXCJMaWNlbnNlXCIpO1xuICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLlxuICpcbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICogICAgIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cbi8qKlxuICogQGZpbGVvdmVydmlldyBUaGlzIHNjcmlwdCBnZW5lcmF0ZXMgQlVJTEQuYmF6ZWwgZmlsZXMgYnkgYW5hbHl6aW5nXG4gKiB0aGUgbm9kZV9tb2R1bGVzIGZvbGRlciBsYXllZCBvdXQgYnkgeWFybiBvciBucG0uIEl0IGdlbmVyYXRlc1xuICogZmluZSBncmFpbmVkIEJhemVsIGBub2RlX21vZHVsZV9saWJyYXJ5YCB0YXJnZXRzIGZvciBlYWNoIHJvb3QgbnBtIHBhY2thZ2VcbiAqIGFuZCBhbGwgZmlsZXMgZm9yIHRoYXQgcGFja2FnZSBhbmQgaXRzIHRyYW5zaXRpdmUgZGVwcyBhcmUgaW5jbHVkZWRcbiAqIGluIHRoZSB0YXJnZXQuIEZvciBleGFtcGxlLCBgQDx3b3Jrc3BhY2U+Ly9qYXNtaW5lYCB3b3VsZFxuICogaW5jbHVkZSBhbGwgZmlsZXMgaW4gdGhlIGphc21pbmUgbnBtIHBhY2thZ2UgYW5kIGFsbCBvZiBpdHNcbiAqIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzLlxuICpcbiAqIG5vZGVqc19iaW5hcnkgdGFyZ2V0cyBhcmUgYWxzbyBnZW5lcmF0ZWQgZm9yIGFsbCBgYmluYCBzY3JpcHRzXG4gKiBpbiBlYWNoIHBhY2thZ2UuIEZvciBleGFtcGxlLCB0aGUgYEA8d29ya3NwYWNlPi8vamFzbWluZS9iaW46amFzbWluZWBcbiAqIHRhcmdldCB3aWxsIGJlIGdlbmVyYXRlZCBmb3IgdGhlIGBqYXNtaW5lYCBiaW5hcnkgaW4gdGhlIGBqYXNtaW5lYFxuICogbnBtIHBhY2thZ2UuXG4gKlxuICogQWRkaXRpb25hbGx5LCBhIGBAPHdvcmtzcGFjZT4vLzpub2RlX21vZHVsZXNgIGBub2RlX21vZHVsZV9saWJyYXJ5YFxuICogaXMgZ2VuZXJhdGVkIHRoYXQgaW5jbHVkZXMgYWxsIHBhY2thZ2VzIHVuZGVyIG5vZGVfbW9kdWxlc1xuICogYXMgd2VsbCBhcyB0aGUgLmJpbiBmb2xkZXIuXG4gKlxuICogVGhpcyB3b3JrIGlzIGJhc2VkIG9mZiB0aGUgZmluZSBncmFpbmVkIGRlcHMgY29uY2VwdHMgaW5cbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9wdWJyZWYvcnVsZXNfbm9kZSBkZXZlbG9wZWQgYnkgQHBjai5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZG9jcy5nb29nbGUuY29tL2RvY3VtZW50L2QvMUFmakhNTFZ5RV92WXdsSFNLN2s3eVdfSUlHcHBTeHNRdFBtOVBUcjF4RW9cbiAqL1xuJ3VzZSBzdHJpY3QnO1xuXG5cbmltcG9ydCAqIGFzIGZzIGZyb20gJ2ZzJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5cbmZ1bmN0aW9uIGxvZ192ZXJib3NlKC4uLm06IGFueVtdKSB7XG4gIGlmICghIXByb2Nlc3MuZW52WydWRVJCT1NFX0xPR1MnXSkgY29uc29sZS5lcnJvcignW2dlbmVyYXRlX2J1aWxkX2ZpbGUuanNdJywgLi4ubSk7XG59XG5cbmNvbnN0IEJVSUxEX0ZJTEVfSEVBREVSID0gYCMgR2VuZXJhdGVkIGZpbGUgZnJvbSB5YXJuX2luc3RhbGwvbnBtX2luc3RhbGwgcnVsZS5cbiMgU2VlICQoYmF6ZWwgaW5mbyBvdXRwdXRfYmFzZSkvZXh0ZXJuYWwvYnVpbGRfYmF6ZWxfcnVsZXNfbm9kZWpzL2ludGVybmFsL25wbV9pbnN0YWxsL2dlbmVyYXRlX2J1aWxkX2ZpbGUuanNcblxuIyBBbGwgcnVsZXMgaW4gb3RoZXIgcmVwb3NpdG9yaWVzIGNhbiB1c2UgdGhlc2UgdGFyZ2V0c1xucGFja2FnZShkZWZhdWx0X3Zpc2liaWxpdHkgPSBbXCIvL3Zpc2liaWxpdHk6cHVibGljXCJdKVxuXG5gXG5cbmNvbnN0IGFyZ3MgPSBwcm9jZXNzLmFyZ3Yuc2xpY2UoMik7XG5jb25zdCBXT1JLU1BBQ0UgPSBhcmdzWzBdO1xuY29uc3QgUlVMRV9UWVBFID0gYXJnc1sxXTtcbmNvbnN0IEVSUk9SX09OX0JBWkVMX0ZJTEVTID0gcGFyc2VJbnQoYXJnc1syXSk7XG5jb25zdCBMT0NLX0ZJTEVfTEFCRUwgPSBhcmdzWzNdO1xuY29uc3QgSU5DTFVERURfRklMRVMgPSBhcmdzWzRdID8gYXJnc1s0XS5zcGxpdCgnLCcpIDogW107XG5jb25zdCBEWU5BTUlDX0RFUFMgPSBKU09OLnBhcnNlKGFyZ3NbNV0gfHwgJ3t9Jyk7XG5cbmlmIChyZXF1aXJlLm1haW4gPT09IG1vZHVsZSkge1xuICBtYWluKCk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IGRpcmVjdG9yeSBhbmQgYW55IG5lY2Vzc2FyeSBzdWJkaXJlY3Rvcmllc1xuICogaWYgdGhleSBkbyBub3QgZXhpc3QuXG4gKi9cbmZ1bmN0aW9uIG1rZGlycChwOiBzdHJpbmcpIHtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKHApKSB7XG4gICAgbWtkaXJwKHBhdGguZGlybmFtZShwKSk7XG4gICAgZnMubWtkaXJTeW5jKHApO1xuICB9XG59XG5cbi8qKlxuICogV3JpdGVzIGEgZmlsZSwgZmlyc3QgZW5zdXJpbmcgdGhhdCB0aGUgZGlyZWN0b3J5IHRvXG4gKiB3cml0ZSB0byBleGlzdHMuXG4gKi9cbmZ1bmN0aW9uIHdyaXRlRmlsZVN5bmMocDogc3RyaW5nLCBjb250ZW50OiBzdHJpbmcpIHtcbiAgbWtkaXJwKHBhdGguZGlybmFtZShwKSk7XG4gIGZzLndyaXRlRmlsZVN5bmMocCwgY29udGVudCk7XG59XG5cbi8qKlxuICogTWFpbiBlbnRyeXBvaW50LlxuICovXG5mdW5jdGlvbiBtYWluKCkge1xuICAvLyBmaW5kIGFsbCBwYWNrYWdlcyAoaW5jbHVkaW5nIHBhY2thZ2VzIGluIG5lc3RlZCBub2RlX21vZHVsZXMpXG4gIGNvbnN0IHBrZ3MgPSBmaW5kUGFja2FnZXMoKTtcblxuICAvLyBmbGF0dGVuIGRlcGVuZGVuY2llc1xuICBmbGF0dGVuRGVwZW5kZW5jaWVzKHBrZ3MpO1xuXG4gIC8vIGdlbmVyYXRlIEJhemVsIHdvcmtzcGFjZXNcbiAgZ2VuZXJhdGVCYXplbFdvcmtzcGFjZXMocGtncylcblxuICAvLyBnZW5lcmF0ZSBhbGwgQlVJTEQgZmlsZXNcbiAgZ2VuZXJhdGVCdWlsZEZpbGVzKHBrZ3MpXG59XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtYWluLFxuICBwcmludFBhY2thZ2VCaW4sXG4gIGFkZER5bmFtaWNEZXBlbmRlbmNpZXMsXG4gIHByaW50SW5kZXhCemwsXG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhbGwgYnVpbGQgZmlsZXNcbiAqL1xuZnVuY3Rpb24gZ2VuZXJhdGVCdWlsZEZpbGVzKHBrZ3M6IERlcFtdKSB7XG4gIGdlbmVyYXRlUm9vdEJ1aWxkRmlsZShwa2dzLmZpbHRlcihwa2cgPT4gIXBrZy5faXNOZXN0ZWQpKVxuICBwa2dzLmZpbHRlcihwa2cgPT4gIXBrZy5faXNOZXN0ZWQpLmZvckVhY2gocGtnID0+IGdlbmVyYXRlUGFja2FnZUJ1aWxkRmlsZXMocGtnKSk7XG4gIGZpbmRTY29wZXMoKS5mb3JFYWNoKHNjb3BlID0+IGdlbmVyYXRlU2NvcGVCdWlsZEZpbGVzKHNjb3BlLCBwa2dzKSk7XG59XG5cbi8qKlxuICogRmxhdHRlbnMgZGVwZW5kZW5jaWVzIG9uIGFsbCBwYWNrYWdlc1xuICovXG5mdW5jdGlvbiBmbGF0dGVuRGVwZW5kZW5jaWVzKHBrZ3M6IERlcFtdKSB7XG4gIGNvbnN0IHBrZ3NNYXAgPSBuZXcgTWFwKCk7XG4gIHBrZ3MuZm9yRWFjaChwa2cgPT4gcGtnc01hcC5zZXQocGtnLl9kaXIsIHBrZykpO1xuICBwa2dzLmZvckVhY2gocGtnID0+IGZsYXR0ZW5Qa2dEZXBlbmRlbmNpZXMocGtnLCBwa2csIHBrZ3NNYXApKTtcbn1cblxuLyoqXG4gKiBIYW5kbGVzIEJhemVsIGZpbGVzIGluIG5wbSBkaXN0cmlidXRpb25zLlxuICovXG5mdW5jdGlvbiBoaWRlQmF6ZWxGaWxlcyhwa2c6IERlcCkge1xuICBjb25zdCBoYXNIaWRlQmF6ZWxGaWxlcyA9IGlzRGlyZWN0b3J5KCdub2RlX21vZHVsZXMvQGJhemVsL2hpZGUtYmF6ZWwtZmlsZXMnKTtcbiAgcGtnLl9maWxlcyA9IHBrZy5fZmlsZXMubWFwKGZpbGUgPT4ge1xuICAgIGNvbnN0IGJhc2VuYW1lID0gcGF0aC5iYXNlbmFtZShmaWxlKTtcbiAgICBjb25zdCBiYXNlbmFtZVVjID0gYmFzZW5hbWUudG9VcHBlckNhc2UoKTtcbiAgICBpZiAoYmFzZW5hbWVVYyA9PT0gJ0JVSUxEJyB8fCBiYXNlbmFtZVVjID09PSAnQlVJTEQuQkFaRUwnKSB7XG4gICAgICAvLyBJZiBiYXplbCBmaWxlcyBhcmUgZGV0ZWN0ZWQgYW5kIHRoZXJlIGlzIG5vIEBiYXplbC9oaWRlLWJhemVsLWZpbGVzIG5wbVxuICAgICAgLy8gcGFja2FnZSB0aGVuIGVycm9yIG91dCBhbmQgc3VnZ2VzdCBhZGRpbmcgdGhlIHBhY2thZ2UuIEl0IGlzIHBvc3NpYmxlIHRvXG4gICAgICAvLyBoYXZlIGJhemVsIEJVSUxEIGZpbGVzIHdpdGggdGhlIHBhY2thZ2UgaW5zdGFsbGVkIGFzIGl0J3MgcG9zdGluc3RhbGxcbiAgICAgIC8vIHN0ZXAsIHdoaWNoIGhpZGVzIGJhemVsIEJVSUxEIGZpbGVzLCBvbmx5IHJ1bnMgd2hlbiB0aGUgQGJhemVsL2hpZGUtYmF6ZWwtZmlsZXNcbiAgICAgIC8vIGlzIGluc3RhbGxlZCBhbmQgbm90IHdoZW4gbmV3IHBhY2thZ2VzIGFyZSBhZGRlZCAodmlhIGB5YXJuIGFkZGBcbiAgICAgIC8vIGZvciBleGFtcGxlKSBhZnRlciB0aGUgaW5pdGlhbCBpbnN0YWxsLiBJbiB0aGlzIGNhc2UsIGhvd2V2ZXIsIHRoZSByZXBvIHJ1bGVcbiAgICAgIC8vIHdpbGwgcmUtcnVuIGFzIHRoZSBwYWNrYWdlLmpzb24gJiYgbG9jayBmaWxlIGhhcyBjaGFuZ2VkIHNvIHdlIGp1c3RcbiAgICAgIC8vIGhpZGUgdGhlIGFkZGVkIEJVSUxEIGZpbGVzIGR1cmluZyB0aGUgcmVwbyBydWxlIHJ1biBoZXJlIHNpbmNlIEBiYXplbC9oaWRlLWJhemVsLWZpbGVzXG4gICAgICAvLyB3YXMgbm90IHJ1bi5cbiAgICAgIGlmICghaGFzSGlkZUJhemVsRmlsZXMgJiYgRVJST1JfT05fQkFaRUxfRklMRVMpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihgbnBtIHBhY2thZ2UgJyR7cGtnLl9kaXJ9JyBmcm9tIEAke1dPUktTUEFDRX0gJHtSVUxFX1RZUEV9IHJ1bGVcbmhhcyBhIEJhemVsIEJVSUxEIGZpbGUgJyR7ZmlsZX0nLiBVc2UgdGhlIEBiYXplbC9oaWRlLWJhemVsLWZpbGVzIHV0aWxpdHkgdG8gaGlkZSB0aGVzZSBmaWxlcy5cblNlZSBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9ydWxlc19ub2RlanMvYmxvYi9tYXN0ZXIvcGFja2FnZXMvaGlkZS1iYXplbC1maWxlcy9SRUFETUUubWRcbmZvciBpbnN0YWxsYXRpb24gaW5zdHJ1Y3Rpb25zLmApO1xuICAgICAgICBwcm9jZXNzLmV4aXQoMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBBbGwgQmF6ZWwgZmlsZXMgaW4gdGhlIG5wbSBkaXN0cmlidXRpb24gc2hvdWxkIGJlIHJlbmFtZWQgYnlcbiAgICAgICAgLy8gYWRkaW5nIGEgYF9gIHByZWZpeCBzbyB0aGF0IGZpbGUgdGFyZ2V0cyBkb24ndCBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMuXG4gICAgICAgIGNvbnN0IG5ld0ZpbGUgPSBwYXRoLnBvc2l4LmpvaW4ocGF0aC5kaXJuYW1lKGZpbGUpLCBgXyR7YmFzZW5hbWV9YCk7XG4gICAgICAgIGNvbnN0IHNyY1BhdGggPSBwYXRoLnBvc2l4LmpvaW4oJ25vZGVfbW9kdWxlcycsIHBrZy5fZGlyLCBmaWxlKTtcbiAgICAgICAgY29uc3QgZHN0UGF0aCA9IHBhdGgucG9zaXguam9pbignbm9kZV9tb2R1bGVzJywgcGtnLl9kaXIsIG5ld0ZpbGUpO1xuICAgICAgICBmcy5yZW5hbWVTeW5jKHNyY1BhdGgsIGRzdFBhdGgpO1xuICAgICAgICByZXR1cm4gbmV3RmlsZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZpbGU7XG4gIH0pO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyB0aGUgcm9vdCBCVUlMRCBmaWxlLlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVJvb3RCdWlsZEZpbGUocGtnczogRGVwW10pIHtcbiAgbGV0IGV4cG9ydHNTdGFybGFyayA9ICcnO1xuICBwa2dzLmZvckVhY2gocGtnID0+IHtwa2cuX2ZpbGVzLmZvckVhY2goZiA9PiB7XG4gICAgICAgICAgICAgICAgIGV4cG9ydHNTdGFybGFyayArPSBgICAgIFwibm9kZV9tb2R1bGVzLyR7cGtnLl9kaXJ9LyR7Zn1cIixcbmA7XG4gICAgICAgICAgICAgICB9KX0pO1xuXG4gIGxldCBzcmNzU3RhcmxhcmsgPSAnJztcbiAgaWYgKHBrZ3MubGVuZ3RoKSB7XG4gICAgY29uc3QgbGlzdCA9IHBrZ3MubWFwKHBrZyA9PiBgXCIvLyR7cGtnLl9kaXJ9OiR7cGtnLl9uYW1lfV9fZmlsZXNcIixgKS5qb2luKCdcXG4gICAgICAgICcpO1xuICAgIHNyY3NTdGFybGFyayA9IGBcbiAgICAjIGRpcmVjdCBzb3VyY2VzIGxpc3RlZCBmb3Igc3RyaWN0IGRlcHMgc3VwcG9ydFxuICAgIHNyY3MgPSBbXG4gICAgICAgICR7bGlzdH1cbiAgICBdLGA7XG4gIH1cblxuICBsZXQgZGVwc1N0YXJsYXJrID0gJyc7XG4gIGlmIChwa2dzLmxlbmd0aCkge1xuICAgIGNvbnN0IGxpc3QgPSBwa2dzLm1hcChwa2cgPT4gYFwiLy8ke3BrZy5fZGlyfToke3BrZy5fbmFtZX1fX2NvbnRlbnRzXCIsYCkuam9pbignXFxuICAgICAgICAnKTtcbiAgICBkZXBzU3RhcmxhcmsgPSBgXG4gICAgIyBmbGF0dGVuZWQgbGlzdCBvZiBkaXJlY3QgYW5kIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIGhvaXN0ZWQgdG8gcm9vdCBieSB0aGUgcGFja2FnZSBtYW5hZ2VyXG4gICAgZGVwcyA9IFtcbiAgICAgICAgJHtsaXN0fVxuICAgIF0sYDtcbiAgfVxuXG4gIGxldCBidWlsZEZpbGUgPSBCVUlMRF9GSUxFX0hFQURFUiArXG4gICAgICBgbG9hZChcIkBidWlsZF9iYXplbF9ydWxlc19ub2RlanMvL2ludGVybmFsL25wbV9pbnN0YWxsOm5vZGVfbW9kdWxlX2xpYnJhcnkuYnpsXCIsIFwibm9kZV9tb2R1bGVfbGlicmFyeVwiKVxuXG5leHBvcnRzX2ZpbGVzKFtcbiR7ZXhwb3J0c1N0YXJsYXJrfV0pXG5cbiMgVGhlIG5vZGVfbW9kdWxlcyBkaXJlY3RvcnkgaW4gb25lIGNhdGNoLWFsbCBub2RlX21vZHVsZV9saWJyYXJ5LlxuIyBOQjogVXNpbmcgdGhpcyB0YXJnZXQgbWF5IGhhdmUgYmFkIHBlcmZvcm1hbmNlIGltcGxpY2F0aW9ucyBpZlxuIyB0aGVyZSBhcmUgbWFueSBmaWxlcyBpbiB0YXJnZXQuXG4jIFNlZSBodHRwczovL2dpdGh1Yi5jb20vYmF6ZWxidWlsZC9iYXplbC9pc3N1ZXMvNTE1My5cbm5vZGVfbW9kdWxlX2xpYnJhcnkoXG4gICAgbmFtZSA9IFwibm9kZV9tb2R1bGVzXCIsJHtzcmNzU3Rhcmxhcmt9JHtkZXBzU3Rhcmxhcmt9XG4pXG5cbmBcblxuICAvLyBBZGQgdGhlIG1hbnVhbCBidWlsZCBmaWxlIGNvbnRlbnRzIGlmIHRoZXkgZXhpc3RzXG4gIHRyeSB7XG4gICAgYnVpbGRGaWxlICs9IGZzLnJlYWRGaWxlU3luYyhgbWFudWFsX2J1aWxkX2ZpbGVfY29udGVudHNgLCB7ZW5jb2Rpbmc6ICd1dGY4J30pO1xuICB9IGNhdGNoIChlKSB7XG4gIH1cblxuICB3cml0ZUZpbGVTeW5jKCdCVUlMRC5iYXplbCcsIGJ1aWxkRmlsZSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGFsbCBCVUlMRCAmIGJ6bCBmaWxlcyBmb3IgYSBwYWNrYWdlLlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVBhY2thZ2VCdWlsZEZpbGVzKHBrZzogRGVwKSB7XG4gIGxldCBidWlsZEZpbGUgPSBwcmludFBhY2thZ2UocGtnKTtcblxuICBjb25zdCBiaW5CdWlsZEZpbGUgPSBwcmludFBhY2thZ2VCaW4ocGtnKTtcbiAgaWYgKGJpbkJ1aWxkRmlsZS5sZW5ndGgpIHtcbiAgICB3cml0ZUZpbGVTeW5jKFxuICAgICAgICBwYXRoLnBvc2l4LmpvaW4ocGtnLl9kaXIsICdiaW4nLCAnQlVJTEQuYmF6ZWwnKSwgQlVJTERfRklMRV9IRUFERVIgKyBiaW5CdWlsZEZpbGUpO1xuICB9XG5cbiAgY29uc3QgaW5kZXhGaWxlID0gcHJpbnRJbmRleEJ6bChwa2cpO1xuICBpZiAoaW5kZXhGaWxlLmxlbmd0aCkge1xuICAgIHdyaXRlRmlsZVN5bmMocGF0aC5wb3NpeC5qb2luKHBrZy5fZGlyLCAnaW5kZXguYnpsJyksIGluZGV4RmlsZSk7XG4gICAgYnVpbGRGaWxlID0gYCR7YnVpbGRGaWxlfVxuIyBGb3IgaW50ZWdyYXRpb24gdGVzdGluZ1xuZXhwb3J0c19maWxlcyhbXCJpbmRleC5iemxcIl0pXG5gO1xuICB9XG5cbiAgd3JpdGVGaWxlU3luYyhwYXRoLnBvc2l4LmpvaW4ocGtnLl9kaXIsICdCVUlMRC5iYXplbCcpLCBCVUlMRF9GSUxFX0hFQURFUiArIGJ1aWxkRmlsZSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgaW5zdGFsbF88d29ya3NwYWNlX25hbWU+LmJ6bCBmaWxlcyB3aXRoIGZ1bmN0aW9uIHRvIGluc3RhbGwgZWFjaCB3b3Jrc3BhY2UuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlQmF6ZWxXb3Jrc3BhY2VzKHBrZ3M6IERlcFtdKSB7XG4gIGNvbnN0IHdvcmtzcGFjZXM6IEJhZzxzdHJpbmc+ID0ge307XG5cbiAgZm9yIChjb25zdCBwa2cgb2YgcGtncykge1xuICAgIGlmICghcGtnLmJhemVsV29ya3NwYWNlcykge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCB3b3Jrc3BhY2Ugb2YgT2JqZWN0LmtleXMocGtnLmJhemVsV29ya3NwYWNlcykpIHtcbiAgICAgIC8vIEEgYmF6ZWwgd29ya3NwYWNlIGNhbiBvbmx5IGJlIHNldHVwIGJ5IG9uZSBucG0gcGFja2FnZVxuICAgICAgaWYgKHdvcmtzcGFjZXNbd29ya3NwYWNlXSkge1xuICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgYENvdWxkIG5vdCBzZXR1cCBCYXplbCB3b3Jrc3BhY2UgJHt3b3Jrc3BhY2V9IHJlcXVlc3RlZCBieSBucG0gYCArXG4gICAgICAgICAgICBgcGFja2FnZSAke3BrZy5fZGlyfUAke3BrZy52ZXJzaW9ufS4gQWxyZWFkeSBzZXR1cCBieSAke3dvcmtzcGFjZXNbd29ya3NwYWNlXX1gKTtcbiAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgfVxuXG4gICAgICBnZW5lcmF0ZUJhemVsV29ya3NwYWNlKHBrZywgd29ya3NwYWNlKTtcblxuICAgICAgLy8gS2VlcCB0cmFjayBvZiB3aGljaCBucG0gcGFja2FnZSBzZXR1cCB0aGlzIGJhemVsIHdvcmtzcGFjZSBmb3IgbGF0ZXIgdXNlXG4gICAgICB3b3Jrc3BhY2VzW3dvcmtzcGFjZV0gPSBgJHtwa2cuX2Rpcn1AJHtwa2cudmVyc2lvbn1gO1xuICAgIH1cbiAgfVxuXG4gIC8vIEZpbmFsbHkgZ2VuZXJhdGUgaW5zdGFsbF9iYXplbF9kZXBlbmRlbmNpZXMuYnpsXG4gIGdlbmVyYXRlSW5zdGFsbEJhemVsRGVwZW5kZW5jaWVzKE9iamVjdC5rZXlzKHdvcmtzcGFjZXMpKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBpbnN0YWxsXzx3b3Jrc3BhY2U+LmJ6bCBmaWxlIHdpdGggZnVuY3Rpb24gdG8gaW5zdGFsbCB0aGUgd29ya3NwYWNlLlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZUJhemVsV29ya3NwYWNlKHBrZzogRGVwLCB3b3Jrc3BhY2U6IHN0cmluZykge1xuICBsZXQgYnpsRmlsZSA9IGAjIEdlbmVyYXRlZCBieSB0aGUgeWFybl9pbnN0YWxsL25wbV9pbnN0YWxsIHJ1bGVcbmxvYWQoXCJAYnVpbGRfYmF6ZWxfcnVsZXNfbm9kZWpzLy9pbnRlcm5hbC9jb3B5X3JlcG9zaXRvcnk6Y29weV9yZXBvc2l0b3J5LmJ6bFwiLCBcImNvcHlfcmVwb3NpdG9yeVwiKVxuXG5kZWYgX21heWJlKHJlcG9fcnVsZSwgbmFtZSwgKiprd2FyZ3MpOlxuICAgIGlmIG5hbWUgbm90IGluIG5hdGl2ZS5leGlzdGluZ19ydWxlcygpOlxuICAgICAgICByZXBvX3J1bGUobmFtZSA9IG5hbWUsICoqa3dhcmdzKVxuYDtcblxuICBjb25zdCByb290UGF0aCA9IHBrZy5iYXplbFdvcmtzcGFjZXNbd29ya3NwYWNlXS5yb290UGF0aDtcbiAgaWYgKCFyb290UGF0aCkge1xuICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgIGBNYWxmb3JtZWQgYmF6ZWxXb3Jrc3BhY2VzIGF0dHJpYnV0ZSBpbiAke3BrZy5fZGlyfUAke3BrZy52ZXJzaW9ufS4gYCArXG4gICAgICAgIGBNaXNzaW5nIHJvb3RQYXRoIGZvciB3b3Jrc3BhY2UgJHt3b3Jrc3BhY2V9LmApO1xuICAgIHByb2Nlc3MuZXhpdCgxKTtcbiAgfVxuXG4gIC8vIENvcHkgYWxsIGZpbGVzIGZvciB0aGlzIHdvcmtzcGFjZSB0byBhIGZvbGRlciB1bmRlciBfd29ya3NwYWNlc1xuICAvLyB0byByZXN0b3JlIHRoZSBCYXplbCBmaWxlcyB3aGljaCBoYXZlIGJlIHJlbmFtZWQgZnJvbSB0aGUgbnBtIHBhY2thZ2VcbiAgY29uc3Qgd29ya3NwYWNlU291cmNlUGF0aCA9IHBhdGgucG9zaXguam9pbignX3dvcmtzcGFjZXMnLCB3b3Jrc3BhY2UpO1xuICBta2RpcnAod29ya3NwYWNlU291cmNlUGF0aCk7XG4gIHBrZy5fZmlsZXMuZm9yRWFjaChmaWxlID0+IHtcbiAgICBpZiAoL15ub2RlX21vZHVsZXNbL1xcXFxdLy50ZXN0KGZpbGUpKSB7XG4gICAgICAvLyBkb24ndCBjb3B5IG92ZXIgbmVzdGVkIG5vZGVfbW9kdWxlc1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgZGVzdEZpbGUgPSBwYXRoLnJlbGF0aXZlKHJvb3RQYXRoLCBmaWxlKTtcbiAgICBpZiAoZGVzdEZpbGUuc3RhcnRzV2l0aCgnLi4nKSkge1xuICAgICAgLy8gdGhpcyBmaWxlIGlzIG5vdCB1bmRlciB0aGUgcm9vdFBhdGhcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYmFzZW5hbWUgPSBwYXRoLmJhc2VuYW1lKGZpbGUpO1xuICAgIGNvbnN0IGJhc2VuYW1lVWMgPSBiYXNlbmFtZS50b1VwcGVyQ2FzZSgpO1xuICAgIC8vIEJhemVsIEJVSUxEIGZpbGVzIGZyb20gbnBtIGRpc3RyaWJ1dGlvbiB3b3VsZCBoYXZlIGJlZW4gcmVuYW1lZCBlYXJsaWVyIHdpdGggYSBfIHByZWZpeCBzb1xuICAgIC8vIHdlIHJlc3RvcmUgdGhlIG5hbWUgb24gdGhlIGNvcHlcbiAgICBpZiAoYmFzZW5hbWVVYyA9PT0gJ19CVUlMRCcgfHwgYmFzZW5hbWVVYyA9PT0gJ19CVUlMRC5CQVpFTCcpIHtcbiAgICAgIGRlc3RGaWxlID0gcGF0aC5wb3NpeC5qb2luKHBhdGguZGlybmFtZShkZXN0RmlsZSksIGJhc2VuYW1lLnN1YnN0cigxKSk7XG4gICAgfVxuICAgIGNvbnN0IHNyYyA9IHBhdGgucG9zaXguam9pbignbm9kZV9tb2R1bGVzJywgcGtnLl9kaXIsIGZpbGUpO1xuICAgIGNvbnN0IGRlc3QgPSBwYXRoLnBvc2l4LmpvaW4od29ya3NwYWNlU291cmNlUGF0aCwgZGVzdEZpbGUpO1xuICAgIG1rZGlycChwYXRoLmRpcm5hbWUoZGVzdCkpO1xuICAgIGZzLmNvcHlGaWxlU3luYyhzcmMsIGRlc3QpO1xuICB9KTtcblxuICAvLyBXZSBjcmVhdGUgX2JhemVsX3dvcmtzcGFjZV9tYXJrZXIgdGhhdCBpcyB1c2VkIGJ5IHRoZSBjdXN0b20gY29weV9yZXBvc2l0b3J5XG4gIC8vIHJ1bGUgdG8gcmVzb2x2ZSB0aGUgcGF0aCB0byB0aGUgcmVwb3NpdG9yeSBzb3VyY2Ugcm9vdC4gQSByb290IEJVSUxEIGZpbGVcbiAgLy8gaXMgcmVxdWlyZWQgdG8gcmVmZXJlbmNlIF9iYXplbF93b3Jrc3BhY2VfbWFya2VyIGFzIGEgdGFyZ2V0IHNvIHdlIGFsc28gY3JlYXRlXG4gIC8vIGFuIGVtcHR5IG9uZSBpZiBvbmUgZG9lcyBub3QgZXhpc3QuXG4gIGlmICghaGFzUm9vdEJ1aWxkRmlsZShwa2csIHJvb3RQYXRoKSkge1xuICAgIHdyaXRlRmlsZVN5bmMoXG4gICAgICAgIHBhdGgucG9zaXguam9pbih3b3Jrc3BhY2VTb3VyY2VQYXRoLCAnQlVJTEQuYmF6ZWwnKSxcbiAgICAgICAgJyMgTWFya2VyIGZpbGUgdGhhdCB0aGlzIGRpcmVjdG9yeSBpcyBhIGJhemVsIHBhY2thZ2UnKTtcbiAgfVxuICB3cml0ZUZpbGVTeW5jKFxuICAgICAgcGF0aC5wb3NpeC5qb2luKHdvcmtzcGFjZVNvdXJjZVBhdGgsICdfYmF6ZWxfd29ya3NwYWNlX21hcmtlcicpLFxuICAgICAgJyMgTWFya2VyIGZpbGUgdG8gdXNlZCBieSBjdXN0b20gY29weV9yZXBvc2l0b3J5IHJ1bGUnKTtcblxuICBiemxGaWxlICs9IGBkZWYgaW5zdGFsbF8ke3dvcmtzcGFjZX0oKTpcbiAgICBfbWF5YmUoXG4gICAgICAgIGNvcHlfcmVwb3NpdG9yeSxcbiAgICAgICAgbmFtZSA9IFwiJHt3b3Jrc3BhY2V9XCIsXG4gICAgICAgIG1hcmtlcl9maWxlID0gXCJAJHtXT1JLU1BBQ0V9Ly9fd29ya3NwYWNlcy8ke3dvcmtzcGFjZX06X2JhemVsX3dvcmtzcGFjZV9tYXJrZXJcIixcbiAgICAgICAgIyBFbnN1cmUgdGhhdCBjaGFuZ2VzIHRvIHRoZSBub2RlX21vZHVsZXMgY2F1c2UgdGhlIGNvcHkgdG8gcmUtZXhlY3V0ZVxuICAgICAgICBsb2NrX2ZpbGUgPSBcIkAke1dPUktTUEFDRX0ke0xPQ0tfRklMRV9MQUJFTH1cIixcbiAgICApXG5gO1xuXG4gIHdyaXRlRmlsZVN5bmMoYGluc3RhbGxfJHt3b3Jrc3BhY2V9LmJ6bGAsIGJ6bEZpbGUpO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIGluc3RhbGxfYmF6ZWxfZGVwZW5kZW5jaWVzLmJ6bCB3aXRoIGZ1bmN0aW9uIHRvIGluc3RhbGwgYWxsIHdvcmtzcGFjZXMuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlSW5zdGFsbEJhemVsRGVwZW5kZW5jaWVzKHdvcmtzcGFjZXM6IHN0cmluZ1tdKSB7XG4gIGxldCBiemxGaWxlID0gYCMgR2VuZXJhdGVkIGJ5IHRoZSB5YXJuX2luc3RhbGwvbnBtX2luc3RhbGwgcnVsZVxuYDtcbiAgd29ya3NwYWNlcy5mb3JFYWNoKHdvcmtzcGFjZSA9PiB7XG4gICAgYnpsRmlsZSArPSBgbG9hZChcXFwiOmluc3RhbGxfJHt3b3Jrc3BhY2V9LmJ6bFxcXCIsIFxcXCJpbnN0YWxsXyR7d29ya3NwYWNlfVxcXCIpXG5gO1xuICB9KTtcbiAgYnpsRmlsZSArPSBgZGVmIGluc3RhbGxfYmF6ZWxfZGVwZW5kZW5jaWVzKCk6XG4gICAgXCJcIlwiSW5zdGFsbHMgYWxsIHdvcmtzcGFjZXMgbGlzdGVkIGluIGJhemVsV29ya3NwYWNlcyBvZiBhbGwgbnBtIHBhY2thZ2VzXCJcIlwiXG5gO1xuICB3b3Jrc3BhY2VzLmZvckVhY2god29ya3NwYWNlID0+IHtcbiAgICBiemxGaWxlICs9IGAgICAgaW5zdGFsbF8ke3dvcmtzcGFjZX0oKVxuYDtcbiAgfSk7XG5cbiAgd3JpdGVGaWxlU3luYygnaW5zdGFsbF9iYXplbF9kZXBlbmRlbmNpZXMuYnpsJywgYnpsRmlsZSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGUgYnVpbGQgZmlsZXMgZm9yIGEgc2NvcGUuXG4gKi9cbmZ1bmN0aW9uIGdlbmVyYXRlU2NvcGVCdWlsZEZpbGVzKHNjb3BlOiBzdHJpbmcsIHBrZ3M6IERlcFtdKSB7XG4gIGNvbnN0IGJ1aWxkRmlsZSA9IEJVSUxEX0ZJTEVfSEVBREVSICsgcHJpbnRTY29wZShzY29wZSwgcGtncyk7XG4gIHdyaXRlRmlsZVN5bmMocGF0aC5wb3NpeC5qb2luKHNjb3BlLCAnQlVJTEQuYmF6ZWwnKSwgYnVpbGRGaWxlKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBwYXRoIGlzIGEgZmlsZS5cbiAqL1xuZnVuY3Rpb24gaXNGaWxlKHA6IHN0cmluZykge1xuICByZXR1cm4gZnMuZXhpc3RzU3luYyhwKSAmJiBmcy5zdGF0U3luYyhwKS5pc0ZpbGUoKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYSBwYXRoIGlzIGFuIG5wbSBwYWNrYWdlIHdoaWNoIGlzIGlzIGEgZGlyZWN0b3J5IHdpdGggYSBwYWNrYWdlLmpzb24gZmlsZS5cbiAqL1xuZnVuY3Rpb24gaXNEaXJlY3RvcnkocDogc3RyaW5nKSB7XG4gIHJldHVybiBmcy5leGlzdHNTeW5jKHApICYmIGZzLnN0YXRTeW5jKHApLmlzRGlyZWN0b3J5KCk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhbiBhcnJheSBvZiBhbGwgdGhlIGZpbGVzIHVuZGVyIGEgZGlyZWN0b3J5IGFzIHJlbGF0aXZlXG4gKiBwYXRocyB0byB0aGUgZGlyZWN0b3J5LlxuICovXG5mdW5jdGlvbiBsaXN0RmlsZXMocm9vdERpcjogc3RyaW5nLCBzdWJEaXI6IHN0cmluZyA9ICcnKTogc3RyaW5nW10ge1xuICBjb25zdCBkaXIgPSBwYXRoLnBvc2l4LmpvaW4ocm9vdERpciwgc3ViRGlyKTtcbiAgaWYgKCFpc0RpcmVjdG9yeShkaXIpKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIHJldHVybiBmcy5yZWFkZGlyU3luYyhkaXIpXG4gICAgICAucmVkdWNlKFxuICAgICAgICAgIChmaWxlczogc3RyaW5nW10sIGZpbGUpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGZ1bGxQYXRoID0gcGF0aC5wb3NpeC5qb2luKGRpciwgZmlsZSk7XG4gICAgICAgICAgICBjb25zdCByZWxQYXRoID0gcGF0aC5wb3NpeC5qb2luKHN1YkRpciwgZmlsZSk7XG4gICAgICAgICAgICBjb25zdCBpc1N5bWJvbGljTGluayA9IGZzLmxzdGF0U3luYyhmdWxsUGF0aCkuaXNTeW1ib2xpY0xpbmsoKTtcbiAgICAgICAgICAgIGxldCBzdGF0O1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgc3RhdCA9IGZzLnN0YXRTeW5jKGZ1bGxQYXRoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgaWYgKGlzU3ltYm9saWNMaW5rKSB7XG4gICAgICAgICAgICAgICAgLy8gRmlsdGVyIG91dCBicm9rZW4gc3ltYm9saWMgbGlua3MuIFRoZXNlIGNhdXNlIGZzLnN0YXRTeW5jKGZ1bGxQYXRoKVxuICAgICAgICAgICAgICAgIC8vIHRvIGZhaWwgd2l0aCBgRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IC4uLmBcbiAgICAgICAgICAgICAgICByZXR1cm4gZmlsZXM7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdGhyb3cgZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGlzRGlyZWN0b3J5ID0gc3RhdC5pc0RpcmVjdG9yeSgpO1xuICAgICAgICAgICAgaWYgKGlzRGlyZWN0b3J5ICYmIGlzU3ltYm9saWNMaW5rKSB7XG4gICAgICAgICAgICAgIC8vIEZpbHRlciBvdXQgc3ltYm9saWMgbGlua3MgdG8gZGlyZWN0b3JpZXMuIEFuIGlzc3VlIGluIHlhcm4gdmVyc2lvbnNcbiAgICAgICAgICAgICAgLy8gb2xkZXIgdGhhbiAxLjEyLjEgY3JlYXRlcyBzeW1ib2xpYyBsaW5rcyB0byBmb2xkZXJzIGluIHRoZSAuYmluIGZvbGRlclxuICAgICAgICAgICAgICAvLyB3aGljaCBsZWFkcyB0byBCYXplbCB0YXJnZXRzIHRoYXQgY3Jvc3MgcGFja2FnZSBib3VuZGFyaWVzLlxuICAgICAgICAgICAgICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2JhemVsYnVpbGQvcnVsZXNfbm9kZWpzL2lzc3Vlcy80MjggYW5kXG4gICAgICAgICAgICAgIC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9iYXplbGJ1aWxkL3J1bGVzX25vZGVqcy9pc3N1ZXMvNDM4LlxuICAgICAgICAgICAgICAvLyBUaGlzIGlzIHRlc3RlZCBpbiAvZTJlL2ZpbmVfZ3JhaW5lZF9zeW1saW5rcy5cbiAgICAgICAgICAgICAgcmV0dXJuIGZpbGVzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGlzRGlyZWN0b3J5ID8gZmlsZXMuY29uY2F0KGxpc3RGaWxlcyhyb290RGlyLCByZWxQYXRoKSkgOiBmaWxlcy5jb25jYXQocmVsUGF0aCk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBbXSlcbiAgICAgIC8vIEZpbGVzIHdpdGggc3BhY2VzIChcXHgyMCkgb3IgdW5pY29kZSBjaGFyYWN0ZXJzICg8XFx4MjAgJiYgPlxceDdFKSBhcmUgbm90IGFsbG93ZWQgaW5cbiAgICAgIC8vIEJhemVsIHJ1bmZpbGVzLiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2JhemVsYnVpbGQvYmF6ZWwvaXNzdWVzLzQzMjdcbiAgICAgIC5maWx0ZXIoZiA9PiAhL1teXFx4MjEtXFx4N0VdLy50ZXN0KGYpKVxuICAgICAgLy8gV2UgcmV0dXJuIGEgc29ydGVkIGFycmF5IHNvIHRoYXQgdGhlIG9yZGVyIG9mIGZpbGVzXG4gICAgICAvLyBpcyB0aGUgc2FtZSByZWdhcmRsZXNzIG9mIHBsYXRmb3JtXG4gICAgICAuc29ydCgpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgbnBtIHBhY2thZ2UgZGlzdHJpYnV0aW9uIGNvbnRhaW5lZCBhXG4gKiByb290IC9CVUlMRCBvciAvQlVJTEQuYmF6ZWwgZmlsZS5cbiAqL1xuZnVuY3Rpb24gaGFzUm9vdEJ1aWxkRmlsZShwa2c6IERlcCwgcm9vdFBhdGg6IHN0cmluZykge1xuICBmb3IgKGNvbnN0IGZpbGUgb2YgcGtnLl9maWxlcykge1xuICAgIC8vIEJhemVsIGZpbGVzIHdvdWxkIGhhdmUgYmVlbiByZW5hbWVkIGVhcmxpZXIgd2l0aCBhIGBfYCBwcmVmaXhcbiAgICBjb25zdCBmaWxlVWMgPSBwYXRoLnJlbGF0aXZlKHJvb3RQYXRoLCBmaWxlKS50b1VwcGVyQ2FzZSgpO1xuICAgIGlmIChmaWxlVWMgPT09ICdfQlVJTEQnIHx8IGZpbGVVYyA9PT0gJ19CVUlMRC5CQVpFTCcpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cblxuZnVuY3Rpb24gYWRkRHluYW1pY0RlcGVuZGVuY2llcyhwa2dzOiBEZXBbXSwgZHluYW1pY19kZXBzID0gRFlOQU1JQ19ERVBTKSB7XG4gIGZ1bmN0aW9uIG1hdGNoKG5hbWU6IHN0cmluZywgcDogRGVwKSB7XG4gICAgLy8gQXV0b21hdGljYWxseSBpbmNsdWRlIGR5bmFtaWMgZGVwZW5kZW5jeSBvbiBwbHVnaW5zIG9mIHRoZSBmb3JtIHBrZy1wbHVnaW4tZm9vXG4gICAgaWYgKG5hbWUuc3RhcnRzV2l0aChgJHtwLl9tb2R1bGVOYW1lfS1wbHVnaW4tYCkpIHJldHVybiB0cnVlO1xuXG4gICAgY29uc3QgdmFsdWUgPSBkeW5hbWljX2RlcHNbcC5fbW9kdWxlTmFtZV07XG4gICAgaWYgKG5hbWUgPT09IHZhbHVlKSByZXR1cm4gdHJ1ZTtcblxuICAgIC8vIFN1cHBvcnQgd2lsZGNhcmQgbWF0Y2hcbiAgICBpZiAodmFsdWUgJiYgdmFsdWUuaW5jbHVkZXMoJyonKSAmJiBuYW1lLnN0YXJ0c1dpdGgodmFsdWUuc3Vic3RyaW5nKDAsIHZhbHVlLmluZGV4T2YoJyonKSkpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcGtncy5mb3JFYWNoKHAgPT4ge1xuICAgIHAuX2R5bmFtaWNEZXBlbmRlbmNpZXMgPSBwa2dzLmZpbHRlcih4ID0+ICEheC5fbW9kdWxlTmFtZSAmJiBtYXRjaCh4Ll9tb2R1bGVOYW1lLCBwKSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoZHluID0+IGAvLyR7ZHluLl9kaXJ9OiR7ZHluLl9uYW1lfWApO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGaW5kcyBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBhbGwgcGFja2FnZXMgdW5kZXIgYSBnaXZlbiBwYXRoLlxuICovXG5mdW5jdGlvbiBmaW5kUGFja2FnZXMocCA9ICdub2RlX21vZHVsZXMnKSB7XG4gIGlmICghaXNEaXJlY3RvcnkocCkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBwa2dzOiBEZXBbXSA9IFtdO1xuXG4gIGNvbnN0IGxpc3RpbmcgPSBmcy5yZWFkZGlyU3luYyhwKTtcblxuICBjb25zdCBwYWNrYWdlcyA9IGxpc3RpbmdcbiAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsdGVyIG91dCBzY29wZXNcbiAgICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihmID0+ICFmLnN0YXJ0c1dpdGgoJ0AnKSlcbiAgICAgICAgICAgICAgICAgICAgICAgLy8gZmlsdGVyIG91dCBmb2xkZXJzIHN1Y2ggYXMgYC5iaW5gIHdoaWNoIGNhbiBjcmVhdGVcbiAgICAgICAgICAgICAgICAgICAgICAgLy8gaXNzdWVzIG9uIFdpbmRvd3Mgc2luY2UgdGhlc2UgYXJlIFwiaGlkZGVuXCIgYnkgZGVmYXVsdFxuICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGYgPT4gIWYuc3RhcnRzV2l0aCgnLicpKVxuICAgICAgICAgICAgICAgICAgICAgICAubWFwKGYgPT4gcGF0aC5wb3NpeC5qb2luKHAsIGYpKVxuICAgICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGYgPT4gaXNEaXJlY3RvcnkoZikpO1xuXG4gIHBhY2thZ2VzLmZvckVhY2goXG4gICAgICBmID0+IHBrZ3MucHVzaChwYXJzZVBhY2thZ2UoZiksIC4uLmZpbmRQYWNrYWdlcyhwYXRoLnBvc2l4LmpvaW4oZiwgJ25vZGVfbW9kdWxlcycpKSkpO1xuXG4gIGNvbnN0IHNjb3BlcyA9IGxpc3RpbmcuZmlsdGVyKGYgPT4gZi5zdGFydHNXaXRoKCdAJykpXG4gICAgICAgICAgICAgICAgICAgICAubWFwKGYgPT4gcGF0aC5wb3NpeC5qb2luKHAsIGYpKVxuICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcihmID0+IGlzRGlyZWN0b3J5KGYpKTtcbiAgc2NvcGVzLmZvckVhY2goZiA9PiBwa2dzLnB1c2goLi4uZmluZFBhY2thZ2VzKGYpKSk7XG5cbiAgYWRkRHluYW1pY0RlcGVuZGVuY2llcyhwa2dzKTtcblxuICByZXR1cm4gcGtncztcbn1cblxuLyoqXG4gKiBGaW5kcyBhbmQgcmV0dXJucyBhbiBhcnJheSBvZiBhbGwgcGFja2FnZSBzY29wZXMgaW4gbm9kZV9tb2R1bGVzLlxuICovXG5mdW5jdGlvbiBmaW5kU2NvcGVzKCkge1xuICBjb25zdCBwID0gJ25vZGVfbW9kdWxlcyc7XG4gIGlmICghaXNEaXJlY3RvcnkocCkpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICBjb25zdCBsaXN0aW5nID0gZnMucmVhZGRpclN5bmMocCk7XG5cbiAgY29uc3Qgc2NvcGVzID0gbGlzdGluZy5maWx0ZXIoZiA9PiBmLnN0YXJ0c1dpdGgoJ0AnKSlcbiAgICAgICAgICAgICAgICAgICAgIC5tYXAoZiA9PiBwYXRoLnBvc2l4LmpvaW4ocCwgZikpXG4gICAgICAgICAgICAgICAgICAgICAuZmlsdGVyKGYgPT4gaXNEaXJlY3RvcnkoZikpXG4gICAgICAgICAgICAgICAgICAgICAubWFwKGYgPT4gZi5yZXBsYWNlKC9ebm9kZV9tb2R1bGVzXFwvLywgJycpKTtcblxuICByZXR1cm4gc2NvcGVzO1xufVxuXG4vKipcbiAqIEdpdmVuIHRoZSBuYW1lIG9mIGEgdG9wLWxldmVsIGZvbGRlciBpbiBub2RlX21vZHVsZXMsIHBhcnNlIHRoZVxuICogcGFja2FnZSBqc29uIGFuZCByZXR1cm4gaXQgYXMgYW4gb2JqZWN0IGFsb25nIHdpdGhcbiAqIHNvbWUgYWRkaXRpb25hbCBpbnRlcm5hbCBhdHRyaWJ1dGVzIHByZWZpeGVkIHdpdGggJ18nLlxuICovXG5mdW5jdGlvbiBwYXJzZVBhY2thZ2UocDogc3RyaW5nKTogRGVwIHtcbiAgLy8gUGFyc2UgdGhlIHBhY2thZ2UuanNvbiBmaWxlIG9mIHRoaXMgcGFja2FnZVxuICBjb25zdCBwYWNrYWdlSnNvbiA9IHBhdGgucG9zaXguam9pbihwLCAncGFja2FnZS5qc29uJyk7XG4gIGNvbnN0IHBrZyA9IGlzRmlsZShwYWNrYWdlSnNvbikgPyBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyhwYWNrYWdlSnNvbiwge2VuY29kaW5nOiAndXRmOCd9KSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3ZlcnNpb246ICcwLjAuMCd9O1xuXG4gIC8vIFRyaW0gdGhlIGxlYWRpbmcgbm9kZV9tb2R1bGVzIGZyb20gdGhlIHBhdGggYW5kXG4gIC8vIGFzc2lnbiB0byBfZGlyIGZvciBmdXR1cmUgdXNlXG4gIHBrZy5fZGlyID0gcC5yZXBsYWNlKC9ebm9kZV9tb2R1bGVzXFwvLywgJycpO1xuXG4gIC8vIFN0YXNoIHRoZSBwYWNrYWdlIGRpcmVjdG9yeSBuYW1lIGZvciBmdXR1cmUgdXNlXG4gIHBrZy5fbmFtZSA9IHBrZy5fZGlyLnNwbGl0KCcvJykucG9wKCk7XG5cbiAgLy8gTW9kdWxlIG5hbWUgb2YgdGhlIHBhY2thZ2UuIFVubGlrZSBcIl9uYW1lXCIgdGhpcyByZXByZXNlbnRzIHRoZVxuICAvLyBmdWxsIHBhY2thZ2UgbmFtZSAoaW5jbHVkaW5nIHNjb3BlIG5hbWUpLlxuICBwa2cuX21vZHVsZU5hbWUgPSBwa2cubmFtZSB8fCBgJHtwa2cuX2Rpcn0vJHtwa2cuX25hbWV9YDtcblxuICAvLyBLZWVwIHRyYWNrIG9mIHdoZXRoZXIgb3Igbm90IHRoaXMgaXMgYSBuZXN0ZWQgcGFja2FnZVxuICBwa2cuX2lzTmVzdGVkID0gL1xcL25vZGVfbW9kdWxlc1xcLy8udGVzdChwKTtcblxuICAvLyBMaXN0IGFsbCB0aGUgZmlsZXMgaW4gdGhlIG5wbSBwYWNrYWdlIGZvciBsYXRlciB1c2VcbiAgcGtnLl9maWxlcyA9IGxpc3RGaWxlcyhwKTtcblxuICAvLyBJbml0aWFsaXplIF9kZXBlbmRlbmNpZXMgdG8gYW4gZW1wdHkgYXJyYXlcbiAgLy8gd2hpY2ggaXMgbGF0ZXIgZmlsbGVkIHdpdGggdGhlIGZsYXR0ZW5lZCBkZXBlbmRlbmN5IGxpc3RcbiAgcGtnLl9kZXBlbmRlbmNpZXMgPSBbXTtcblxuICAvLyBIaWRlIGJhemVsIGZpbGVzIGluIHRoaXMgcGFja2FnZS4gV2UgZG8gdGhpcyBiZWZvcmUgcGFyc2luZ1xuICAvLyB0aGUgbmV4dCBwYWNrYWdlIHRvIHByZXZlbnQgaXNzdWVzIGNhdXNlZCBieSBzeW1saW5rcyBiZXR3ZWVuXG4gIC8vIHBhY2thZ2UgYW5kIG5lc3RlZCBwYWNrYWdlcyBzZXR1cCBieSB0aGUgcGFja2FnZSBtYW5hZ2VyLlxuICBoaWRlQmF6ZWxGaWxlcyhwa2cpO1xuXG4gIHJldHVybiBwa2c7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgYSBiaW4gZW50cnkgaXMgYSBub24tZW1wdHkgcGF0aFxuICovXG5mdW5jdGlvbiBpc1ZhbGlkQmluUGF0aChlbnRyeTogYW55KSB7XG4gIHJldHVybiBpc1ZhbGlkQmluUGF0aFN0cmluZ1ZhbHVlKGVudHJ5KSB8fCBpc1ZhbGlkQmluUGF0aE9iamVjdFZhbHVlcyhlbnRyeSk7XG59XG5cbi8qKlxuICogSWYgZ2l2ZW4gYSBzdHJpbmcsIGNoZWNrIGlmIGEgYmluIGVudHJ5IGlzIGEgbm9uLWVtcHR5IHBhdGhcbiAqL1xuZnVuY3Rpb24gaXNWYWxpZEJpblBhdGhTdHJpbmdWYWx1ZShlbnRyeTogYW55KSB7XG4gIHJldHVybiB0eXBlb2YgZW50cnkgPT09ICdzdHJpbmcnICYmIGVudHJ5ICE9PSAnJztcbn1cblxuLyoqXG4gKiBJZiBnaXZlbiBhbiBvYmplY3QgbGl0ZXJhbCwgY2hlY2sgaWYgYSBiaW4gZW50cnkgb2JqZWN0cyBoYXMgYXQgbGVhc3Qgb25lIGEgbm9uLWVtcHR5IHBhdGhcbiAqIEV4YW1wbGUgMTogeyBlbnRyeTogJy4vcGF0aC90by9zY3JpcHQuanMnIH0gPT0+IFZBTElEXG4gKiBFeGFtcGxlIDI6IHsgZW50cnk6ICcnIH0gPT0+IElOVkFMSURcbiAqIEV4YW1wbGUgMzogeyBlbnRyeTogJy4vcGF0aC90by9zY3JpcHQuanMnLCBlbXB0eTogJycgfSA9PT4gVkFMSURcbiAqL1xuZnVuY3Rpb24gaXNWYWxpZEJpblBhdGhPYmplY3RWYWx1ZXMoZW50cnk6IEJhZzxzdHJpbmc+KTogYm9vbGVhbiB7XG4gIC8vIFdlIGFsbG93IGF0IGxlYXN0IG9uZSB2YWxpZCBlbnRyeSBwYXRoIChpZiBhbnkpLlxuICByZXR1cm4gZW50cnkgJiYgdHlwZW9mIGVudHJ5ID09PSAnb2JqZWN0JyAmJlxuICAgICAgT2JqZWN0Wyd2YWx1ZXMnXShlbnRyeSkuZmlsdGVyKF9lbnRyeSA9PiBpc1ZhbGlkQmluUGF0aChfZW50cnkpKS5sZW5ndGggPiAwO1xufVxuXG4vKipcbiAqIENsZWFudXAgYSBwYWNrYWdlLmpzb24gXCJiaW5cIiBwYXRoLlxuICpcbiAqIEJpbiBwYXRocyB1c3VhbGx5IGNvbWUgaW4gMiBmbGF2b3JzOiAnLi9iaW4vZm9vJyBvciAnYmluL2ZvbycsXG4gKiBzb21ldGltZXMgb3RoZXIgc3R1ZmYgbGlrZSAnbGliL2ZvbycuICBSZW1vdmUgcHJlZml4ICcuLycgaWYgaXRcbiAqIGV4aXN0cy5cbiAqL1xuZnVuY3Rpb24gY2xlYW51cEJpblBhdGgocDogc3RyaW5nKSB7XG4gIHAgPSBwLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgaWYgKHAuaW5kZXhPZignLi8nKSA9PT0gMCkge1xuICAgIHAgPSBwLnNsaWNlKDIpO1xuICB9XG4gIHJldHVybiBwO1xufVxuXG4vKipcbiAqIENsZWFudXAgYSBwYWNrYWdlLmpzb24gZW50cnkgcG9pbnQgc3VjaCBhcyBcIm1haW5cIlxuICpcbiAqIFJlbW92ZXMgJy4vJyBpZiBpdCBleGlzdHMuXG4gKiBBcHBlbmRzIGBpbmRleC5qc2AgaWYgcCBlbmRzIHdpdGggYC9gLlxuICovXG5mdW5jdGlvbiBjbGVhbnVwRW50cnlQb2ludFBhdGgocDogc3RyaW5nKSB7XG4gIHAgPSBwLnJlcGxhY2UoL1xcXFwvZywgJy8nKTtcbiAgaWYgKHAuaW5kZXhPZignLi8nKSA9PT0gMCkge1xuICAgIHAgPSBwLnNsaWNlKDIpO1xuICB9XG4gIGlmIChwLmVuZHNXaXRoKCcvJykpIHtcbiAgICBwICs9ICdpbmRleC5qcyc7XG4gIH1cbiAgcmV0dXJuIHA7XG59XG5cbi8qKlxuICogQ2xlYW5zIHVwIHRoZSBnaXZlbiBwYXRoXG4gKiBUaGVuIHRyaWVzIHRvIHJlc29sdmUgdGhlIHBhdGggaW50byBhIGZpbGUgYW5kIHdhcm5zIGlmIFZFUkJPU0VfTE9HUyBzZXQgYW5kIHRoZSBmaWxlIGRvc2VuJ3RcbiAqIGV4aXN0XG4gKiBAcGFyYW0ge2FueX0gcGtnXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aFxuICogQHJldHVybnMge3N0cmluZyB8IHVuZGVmaW5lZH1cbiAqL1xuZnVuY3Rpb24gZmluZEVudHJ5RmlsZShwa2c6IERlcCwgcGF0aDogc3RyaW5nKSB7XG4gIGNvbnN0IGNsZWFuUGF0aCA9IGNsZWFudXBFbnRyeVBvaW50UGF0aChwYXRoKTtcbiAgLy8gY2hlY2sgaWYgbWFpbiBlbnRyeSBwb2ludCBleGlzdHNcbiAgY29uc3QgZW50cnlGaWxlID0gZmluZEZpbGUocGtnLCBjbGVhblBhdGgpIHx8IGZpbmRGaWxlKHBrZywgYCR7Y2xlYW5QYXRofS5qc2ApO1xuICBpZiAoIWVudHJ5RmlsZSkge1xuICAgIC8vIElmIGVudHJ5UG9pbnQgZW50cnkgcG9pbnQgbGlzdGVkIGNvdWxkIG5vdCBiZSByZXNvbHZlZCB0byBhIGZpbGVcbiAgICAvLyBUaGlzIGNhbiBoYXBwZW5cbiAgICAvLyBpbiBzb21lIG5wbSBwYWNrYWdlcyB0aGF0IGxpc3QgYW4gaW5jb3JyZWN0IG1haW4gc3VjaCBhcyB2OC1jb3ZlcmFnZUAxLjAuOFxuICAgIC8vIHdoaWNoIGxpc3RzIGBcIm1haW5cIjogXCJpbmRleC5qc1wiYCBidXQgdGhhdCBmaWxlIGRvZXMgbm90IGV4aXN0LlxuICAgIGxvZ192ZXJib3NlKFxuICAgICAgICBgY291bGQgbm90IGZpbmQgZW50cnkgcG9pbnQgZm9yIHRoZSBwYXRoICR7Y2xlYW5QYXRofSBnaXZlbiBieSBucG0gcGFja2FnZSAke3BrZy5fbmFtZX1gKTtcbiAgfVxuICByZXR1cm4gZW50cnlGaWxlO1xufVxuXG4vKipcbiAqIFRyaWVzIHRvIHJlc29sdmUgdGhlIGVudHJ5UG9pbnQgZmlsZSBmcm9tIHRoZSBwa2cgZm9yIGEgZ2l2ZW4gbWFpbkZpbGVOYW1lXG4gKlxuICogQHBhcmFtIHthbnl9IHBrZ1xuICogQHBhcmFtIHsnYnJvd3NlcicgfCAnbW9kdWxlJyB8ICdtYWluJ30gbWFpbkZpbGVOYW1lXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfSB0aGUgcGF0aCBvciB1bmRlZmluZWQgaWYgd2UgY2FudCByZXNvbHZlIHRoZSBmaWxlXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVNYWluRmlsZShwa2c6IERlcCwgbWFpbkZpbGVOYW1lOiBzdHJpbmcpIHtcbiAgY29uc3QgbWFpbkVudHJ5RmllbGQgPSBwa2dbbWFpbkZpbGVOYW1lXTtcblxuICBpZiAobWFpbkVudHJ5RmllbGQpIHtcbiAgICBpZiAodHlwZW9mIG1haW5FbnRyeUZpZWxkID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGZpbmRFbnRyeUZpbGUocGtnLCBtYWluRW50cnlGaWVsZClcblxuICAgIH0gZWxzZSBpZiAodHlwZW9mIG1haW5FbnRyeUZpZWxkID09PSAnb2JqZWN0JyAmJiBtYWluRmlsZU5hbWUgPT09ICdicm93c2VyJykge1xuICAgICAgLy8gYnJvd3NlciBoYXMgYSB3ZWlyZCB3YXkgb2YgZGVmaW5pbmcgdGhpc1xuICAgICAgLy8gdGhlIGJyb3dzZXIgdmFsdWUgaXMgYW4gb2JqZWN0IGxpc3RpbmcgZmlsZXMgdG8gYWxpYXMsIHVzdWFsbHkgcG9pbnRpbmcgdG8gYSBicm93c2VyIGRpclxuICAgICAgY29uc3QgaW5kZXhFbnRyeVBvaW50ID0gbWFpbkVudHJ5RmllbGRbJ2luZGV4LmpzJ10gfHwgbWFpbkVudHJ5RmllbGRbJy4vaW5kZXguanMnXTtcbiAgICAgIGlmIChpbmRleEVudHJ5UG9pbnQpIHtcbiAgICAgICAgcmV0dXJuIGZpbmRFbnRyeUZpbGUocGtnLCBpbmRleEVudHJ5UG9pbnQpXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogVHJpZXMgdG8gcmVzb2x2ZSB0aGUgbWFpbkZpbGUgZnJvbSBhIGdpdmVuIHBrZ1xuICogVGhpcyB1c2VzIHNldmVhbCBtYWluRmlsZU5hbWVzIGluIHByaW9yaXR5IHRvIGZpbmQgYSBjb3JyZWN0IHVzYWJsZSBmaWxlXG4gKiBAcGFyYW0ge2FueX0gcGtnXG4gKiBAcmV0dXJucyB7c3RyaW5nIHwgdW5kZWZpbmVkfVxuICovXG5mdW5jdGlvbiByZXNvbHZlUGtnTWFpbkZpbGUocGtnOiBEZXApIHtcbiAgLy8gZXMyMDE1IGlzIGFub3RoZXIgb3B0aW9uIGZvciBtYWluRmlsZSBoZXJlXG4gIC8vIGJ1dCBpdHMgdmVyeSB1bmNvbW1vbiBhbmQgaW0gbm90IHN1cmUgd2hhdCBwcmlvcml0eSBpdCB0YWtlc1xuICAvL1xuICAvLyB0aGlzIGxpc3QgaXMgb3JkZXJlZCwgd2UgdHJ5IHJlc29sdmUgYGJyb3dzZXJgIGZpcnN0LCB0aGVuIGBtb2R1bGVgIGFuZCBmaW5hbGx5IGZhbGwgYmFjayB0b1xuICAvLyBgbWFpbmBcbiAgY29uc3QgbWFpbkZpbGVOYW1lcyA9IFsnYnJvd3NlcicsICdtb2R1bGUnLCAnbWFpbiddXG5cbiAgICAgIGZvciAoY29uc3QgbWFpbkZpbGUgb2YgbWFpbkZpbGVOYW1lcykge1xuICAgIGNvbnN0IHJlc29sdmVkTWFpbkZpbGUgPSByZXNvbHZlTWFpbkZpbGUocGtnLCBtYWluRmlsZSk7XG4gICAgaWYgKHJlc29sdmVkTWFpbkZpbGUpIHtcbiAgICAgIHJldHVybiByZXNvbHZlZE1haW5GaWxlO1xuICAgIH1cbiAgfVxuXG4gIC8vIGlmIHdlIGNhbnQgZmluZCBhbnkgY29ycmVjdCBmaWxlIHJlZmVyZW5jZXMgZnJvbSB0aGUgcGtnXG4gIC8vIHRoZW4gd2UganVzdCB0cnkgbG9va2luZyBhcm91bmQgZm9yIGNvbW1vbiBwYXR0ZXJuc1xuICBjb25zdCBtYXliZVJvb3RJbmRleCA9IGZpbmRFbnRyeUZpbGUocGtnLCAnaW5kZXguanMnKTtcbiAgaWYgKG1heWJlUm9vdEluZGV4KSB7XG4gICAgcmV0dXJuIG1heWJlUm9vdEluZGV4XG4gIH1cblxuICBjb25zdCBtYXliZVNlbGZOYW1lZEluZGV4ID0gZmluZEVudHJ5RmlsZShwa2csIGAke3BrZy5fbmFtZX0uanNgKTtcbiAgaWYgKG1heWJlU2VsZk5hbWVkSW5kZXgpIHtcbiAgICByZXR1cm4gbWF5YmVTZWxmTmFtZWRJbmRleDtcbiAgfVxuXG4gIC8vIG5vbmUgb2YgdGhlIG1ldGhvZHMgd2UgdHJpZWQgcmVzdWx0ZWQgaW4gYSBmaWxlXG4gIGxvZ192ZXJib3NlKGBjb3VsZCBub3QgZmluZCBlbnRyeSBwb2ludCBmb3IgbnBtIHBhY2thZ2UgJHtwa2cuX25hbWV9YCk7XG5cbiAgLy8gYXQgdGhpcyBwb2ludCB0aGVyZSdzIG5vdGhpbmcgbGVmdCBmb3IgdXMgdG8gdHJ5LCBzbyByZXR1cm4gbm90aGluZ1xuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG50eXBlIEJhZzxUPiA9XG4gICAge1xuICAgICAgW2s6IHN0cmluZ106IFRcbiAgICB9XG5cbi8qKlxuICogRmxhdHRlbnMgYWxsIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIG9mIGEgcGFja2FnZVxuICogaW50byBhIF9kZXBlbmRlbmNpZXMgYXJyYXkuXG4gKi9cbmZ1bmN0aW9uIGZsYXR0ZW5Qa2dEZXBlbmRlbmNpZXMocGtnOiBEZXAsIGRlcDogRGVwLCBwa2dzTWFwOiBNYXA8c3RyaW5nLCBEZXA+KSB7XG4gIGlmIChwa2cuX2RlcGVuZGVuY2llcy5pbmRleE9mKGRlcCkgIT09IC0xKSB7XG4gICAgLy8gY2lyY3VsYXIgZGVwZW5kZW5jeVxuICAgIHJldHVybjtcbiAgfVxuICBwa2cuX2RlcGVuZGVuY2llcy5wdXNoKGRlcCk7XG4gIGNvbnN0IGZpbmREZXBzID0gZnVuY3Rpb24odGFyZ2V0RGVwczogQmFnPHN0cmluZz4sIHJlcXVpcmVkOiBib29sZWFuLCBkZXBUeXBlOiBzdHJpbmcpIHtcbiAgICBPYmplY3Qua2V5cyh0YXJnZXREZXBzIHx8IHt9KVxuICAgICAgICAubWFwKHRhcmdldERlcCA9PiB7XG4gICAgICAgICAgLy8gbG9vayBmb3IgbWF0Y2hpbmcgbmVzdGVkIHBhY2thZ2VcbiAgICAgICAgICBjb25zdCBkaXJTZWdtZW50cyA9IGRlcC5fZGlyLnNwbGl0KCcvJyk7XG4gICAgICAgICAgd2hpbGUgKGRpclNlZ21lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc3QgbWF5YmUgPSBwYXRoLnBvc2l4LmpvaW4oLi4uZGlyU2VnbWVudHMsICdub2RlX21vZHVsZXMnLCB0YXJnZXREZXApO1xuICAgICAgICAgICAgaWYgKHBrZ3NNYXAuaGFzKG1heWJlKSkge1xuICAgICAgICAgICAgICByZXR1cm4gcGtnc01hcC5nZXQobWF5YmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGlyU2VnbWVudHMucG9wKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIGxvb2sgZm9yIG1hdGNoaW5nIHJvb3QgcGFja2FnZVxuICAgICAgICAgIGlmIChwa2dzTWFwLmhhcyh0YXJnZXREZXApKSB7XG4gICAgICAgICAgICByZXR1cm4gcGtnc01hcC5nZXQodGFyZ2V0RGVwKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gZGVwZW5kZW5jeSBub3QgZm91bmRcbiAgICAgICAgICBpZiAocmVxdWlyZWQpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYGNvdWxkIG5vdCBmaW5kICR7ZGVwVHlwZX0gJyR7dGFyZ2V0RGVwfScgb2YgJyR7ZGVwLl9kaXJ9J2ApO1xuICAgICAgICAgICAgcHJvY2Vzcy5leGl0KDEpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfSlcbiAgICAgICAgLmZpbHRlcihkZXAgPT4gISFkZXApXG4gICAgICAgIC5mb3JFYWNoKGRlcCA9PiBmbGF0dGVuUGtnRGVwZW5kZW5jaWVzKHBrZywgZGVwISwgcGtnc01hcCkpO1xuICB9O1xuICAvLyBucG0gd2lsbCBpbiBzb21lIGNhc2VzIGFkZCBvcHRpb25hbERlcGVuZGVuY2llcyB0byB0aGUgbGlzdFxuICAvLyBvZiBkZXBlbmRlbmNpZXMgdG8gdGhlIHBhY2thZ2UuanNvbiBpdCB3cml0ZXMgdG8gbm9kZV9tb2R1bGVzLlxuICAvLyBXZSBkZWxldGUgdGhlc2UgaGVyZSBpZiB0aGV5IGV4aXN0IGFzIHRoZXkgbWF5IHJlc3VsdFxuICAvLyBpbiBleHBlY3RlZCBkZXBlbmRlbmNpZXMgdGhhdCBhcmUgbm90IGZvdW5kLlxuICBpZiAoZGVwLmRlcGVuZGVuY2llcyAmJiBkZXAub3B0aW9uYWxEZXBlbmRlbmNpZXMpIHtcbiAgICBPYmplY3Qua2V5cyhkZXAub3B0aW9uYWxEZXBlbmRlbmNpZXMpLmZvckVhY2gob3B0aW9uYWxEZXAgPT4ge1xuICAgICAgZGVsZXRlIGRlcC5kZXBlbmRlbmNpZXNbb3B0aW9uYWxEZXBdO1xuICAgIH0pO1xuICB9XG5cbiAgZmluZERlcHMoZGVwLmRlcGVuZGVuY2llcywgdHJ1ZSwgJ2RlcGVuZGVuY3knKTtcbiAgZmluZERlcHMoZGVwLnBlZXJEZXBlbmRlbmNpZXMsIHRydWUsICdwZWVyIGRlcGVuZGVuY3knKTtcbiAgLy8gYG9wdGlvbmFsRGVwZW5kZW5jaWVzYCB0aGF0IGFyZSBtaXNzaW5nIHNob3VsZCBiZSBzaWxlbnRseVxuICAvLyBpZ25vcmVkIHNpbmNlIHRoZSBucG0veWFybiB3aWxsIG5vdCBmYWlsIGlmIHRoZXNlIGRlcGVuZGVuY2llc1xuICAvLyBmYWlsIHRvIGluc3RhbGwuIFBhY2thZ2VzIHNob3VsZCBoYW5kbGUgdGhlIGNhc2VzIHdoZXJlIHRoZXNlXG4gIC8vIGRlcGVuZGVuY2llcyBhcmUgbWlzc2luZyBncmFjZWZ1bGx5IGF0IHJ1bnRpbWUuXG4gIC8vIEFuIGV4YW1wbGUgb2YgdGhpcyBpcyB0aGUgYGNob2tpZGFyYCBwYWNrYWdlIHdoaWNoIHNwZWNpZmllc1xuICAvLyBgZnNldmVudHNgIGFzIGFuIG9wdGlvbmFsRGVwZW5kZW5jeS4gT24gT1NYLCBgZnNldmVudHNgXG4gIC8vIGlzIGluc3RhbGxlZCBzdWNjZXNzZnVsbHksIGJ1dCBvbiBXaW5kb3dzICYgTGludXgsIGBmc2V2ZW50c2BcbiAgLy8gZmFpbHMgdG8gaW5zdGFsbCBhbmQgdGhlIHBhY2thZ2Ugd2lsbCBub3QgYmUgcHJlc2VudCB3aGVuXG4gIC8vIGNoZWNraW5nIHRoZSBkZXBlbmRlbmNpZXMgb2YgYGNob2tpZGFyYC5cbiAgZmluZERlcHMoZGVwLm9wdGlvbmFsRGVwZW5kZW5jaWVzLCBmYWxzZSwgJ29wdGlvbmFsIGRlcGVuZGVuY3knKTtcbn1cblxuLyoqXG4gKiBSZWZvcm1hdC9wcmV0dHktcHJpbnQgYSBqc29uIG9iamVjdCBhcyBhIHNreWxhcmsgY29tbWVudCAoZWFjaCBsaW5lXG4gKiBzdGFydHMgd2l0aCAnIyAnKS5cbiAqL1xuZnVuY3Rpb24gcHJpbnRKc29uKHBrZzogRGVwKSB7XG4gIC8vIENsb25lIGFuZCBtb2RpZnkgX2RlcGVuZGVuY2llcyB0byBhdm9pZCBjaXJjdWxhciBpc3N1ZXMgd2hlbiBKU09OaWZ5aW5nXG4gIC8vICYgZGVsZXRlIF9maWxlcyBhcnJheVxuICBjb25zdCBjbG9uZWQ6IGFueSA9IHsuLi5wa2d9O1xuICBjbG9uZWQuX2RlcGVuZGVuY2llcyA9IHBrZy5fZGVwZW5kZW5jaWVzLm1hcChkZXAgPT4gZGVwLl9kaXIpO1xuICBkZWxldGUgY2xvbmVkLl9maWxlcztcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGNsb25lZCwgbnVsbCwgMikuc3BsaXQoJ1xcbicpLm1hcChsaW5lID0+IGAjICR7bGluZX1gKS5qb2luKCdcXG4nKTtcbn1cblxuLyoqXG4gKiBBIGZpbHRlciBmdW5jdGlvbiBmb3IgZmlsZXMgaW4gYW4gbnBtIHBhY2thZ2UuIENvbXBhcmlzb24gaXMgY2FzZS1pbnNlbnNpdGl2ZS5cbiAqIEBwYXJhbSBmaWxlcyBhcnJheSBvZiBmaWxlcyB0byBmaWx0ZXJcbiAqIEBwYXJhbSBleHRzIGxpc3Qgb2Ygd2hpdGUgbGlzdGVkIGNhc2UtaW5zZW5zaXRpdmUgZXh0ZW5zaW9uczsgaWYgZW1wdHksIG5vIGZpbHRlciBpc1xuICogICAgICAgICAgICAgZG9uZSBvbiBleHRlbnNpb25zOyAnJyBlbXB0eSBzdHJpbmcgZGVub3RlcyB0byBhbGxvdyBmaWxlcyB3aXRoIG5vIGV4dGVuc2lvbnMsXG4gKiAgICAgICAgICAgICBvdGhlciBleHRlbnNpb25zIGFyZSBsaXN0ZWQgd2l0aCAnLmV4dCcgbm90YXRpb24gc3VjaCBhcyAnLmQudHMnLlxuICovXG5mdW5jdGlvbiBmaWx0ZXJGaWxlcyhmaWxlczogc3RyaW5nW10sIGV4dHM6IHN0cmluZ1tdID0gW10pIHtcbiAgaWYgKGV4dHMubGVuZ3RoKSB7XG4gICAgY29uc3QgYWxsb3dOb0V4dHMgPSBleHRzLmluY2x1ZGVzKCcnKTtcbiAgICBmaWxlcyA9IGZpbGVzLmZpbHRlcihmID0+IHtcbiAgICAgIC8vIGluY2x1ZGUgZmlsZXMgd2l0aCBubyBleHRlbnNpb25zIGlmIG5vRXh0IGlzIHRydWVcbiAgICAgIGlmIChhbGxvd05vRXh0cyAmJiAhcGF0aC5leHRuYW1lKGYpKSByZXR1cm4gdHJ1ZTtcbiAgICAgIC8vIGZpbHRlciBmaWxlcyBpbiBleHRzXG4gICAgICBjb25zdCBsYyA9IGYudG9Mb3dlckNhc2UoKTtcbiAgICAgIGZvciAoY29uc3QgZSBvZiBleHRzKSB7XG4gICAgICAgIGlmIChlICYmIGxjLmVuZHNXaXRoKGUudG9Mb3dlckNhc2UoKSkpIHtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pXG4gIH1cbiAgLy8gRmlsdGVyIG91dCBCVUlMRCBmaWxlcyB0aGF0IGNhbWUgd2l0aCB0aGUgbnBtIHBhY2thZ2VcbiAgcmV0dXJuIGZpbGVzLmZpbHRlcihmaWxlID0+IHtcbiAgICBjb25zdCBiYXNlbmFtZVVjID0gcGF0aC5iYXNlbmFtZShmaWxlKS50b1VwcGVyQ2FzZSgpO1xuICAgIGlmIChiYXNlbmFtZVVjID09PSAnX0JVSUxEJyB8fCBiYXNlbmFtZVVjID09PSAnX0JVSUxELkJBWkVMJykge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSk7XG59XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBzcGVjaWZpZWQgYHBrZ2AgY29uZm9ybXMgdG8gQW5ndWxhciBQYWNrYWdlIEZvcm1hdCAoQVBGKSxcbiAqIGZhbHNlIG90aGVyd2lzZS4gSWYgdGhlIHBhY2thZ2UgY29udGFpbnMgYCoubWV0YWRhdGEuanNvbmAgYW5kIGFcbiAqIGNvcnJlc3BvbmRpbmcgc2libGluZyBgLmQudHNgIGZpbGUsIHRoZW4gdGhlIHBhY2thZ2UgaXMgY29uc2lkZXJlZCB0byBiZSBBUEYuXG4gKi9cbmZ1bmN0aW9uIGlzTmdBcGZQYWNrYWdlKHBrZzogRGVwKSB7XG4gIGNvbnN0IHNldCA9IG5ldyBTZXQocGtnLl9maWxlcyk7XG4gIGlmIChzZXQuaGFzKCdBTkdVTEFSX1BBQ0tBR0UnKSkge1xuICAgIC8vIFRoaXMgZmlsZSBpcyB1c2VkIGJ5IHRoZSBucG0veWFybl9pbnN0YWxsIHJ1bGUgdG8gZGV0ZWN0IEFQRi4gU2VlXG4gICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2JhemVsYnVpbGQvcnVsZXNfbm9kZWpzL2lzc3Vlcy85MjdcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBjb25zdCBtZXRhZGF0YUV4dCA9IC9cXC5tZXRhZGF0YVxcLmpzb24kLztcbiAgcmV0dXJuIHBrZy5fZmlsZXMuc29tZSgoZmlsZSkgPT4ge1xuICAgIGlmIChtZXRhZGF0YUV4dC50ZXN0KGZpbGUpKSB7XG4gICAgICBjb25zdCBzaWJsaW5nID0gZmlsZS5yZXBsYWNlKG1ldGFkYXRhRXh0LCAnLmQudHMnKTtcbiAgICAgIGlmIChzZXQuaGFzKHNpYmxpbmcpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH0pO1xufVxuXG4vKipcbiAqIElmIHRoZSBwYWNrYWdlIGlzIGluIHRoZSBBbmd1bGFyIHBhY2thZ2UgZm9ybWF0IHJldHVybnMgbGlzdFxuICogb2YgcGFja2FnZSBmaWxlcyB0aGF0IGVuZCB3aXRoIGAudW1kLmpzYCwgYC5uZ2ZhY3RvcnkuanNgIGFuZCBgLm5nc3VtbWFyeS5qc2AuXG4gKi9cbmZ1bmN0aW9uIGdldE5nQXBmU2NyaXB0cyhwa2c6IERlcCkge1xuICByZXR1cm4gaXNOZ0FwZlBhY2thZ2UocGtnKSA/XG4gICAgICBmaWx0ZXJGaWxlcyhwa2cuX2ZpbGVzLCBbJy51bWQuanMnLCAnLm5nZmFjdG9yeS5qcycsICcubmdzdW1tYXJ5LmpzJ10pIDpcbiAgICAgIFtdO1xufVxuXG4vKipcbiAqIExvb2tzIGZvciBhIGZpbGUgd2l0aGluIGEgcGFja2FnZSBhbmQgcmV0dXJucyBpdCBpZiBmb3VuZC5cbiAqL1xuZnVuY3Rpb24gZmluZEZpbGUocGtnOiBEZXAsIG06IHN0cmluZykge1xuICBjb25zdCBtbCA9IG0udG9Mb3dlckNhc2UoKTtcbiAgZm9yIChjb25zdCBmIG9mIHBrZy5fZmlsZXMpIHtcbiAgICBpZiAoZi50b0xvd2VyQ2FzZSgpID09PSBtbCkge1xuICAgICAgcmV0dXJuIGY7XG4gICAgfVxuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogR2l2ZW4gYSBwa2csIHJldHVybiB0aGUgc2t5bGFyayBgbm9kZV9tb2R1bGVfbGlicmFyeWAgdGFyZ2V0cyBmb3IgdGhlIHBhY2thZ2UuXG4gKi9cbmZ1bmN0aW9uIHByaW50UGFja2FnZShwa2c6IERlcCkge1xuICBjb25zdCBzb3VyY2VzID0gZmlsdGVyRmlsZXMocGtnLl9maWxlcywgSU5DTFVERURfRklMRVMpO1xuICBjb25zdCBkdHNTb3VyY2VzID0gZmlsdGVyRmlsZXMocGtnLl9maWxlcywgWycuZC50cyddKTtcbiAgLy8gVE9ETyhnbWFnb2xhbik6IGFkZCBVTUQgJiBBTUQgc2NyaXB0cyB0byBzY3JpcHRzIGV2ZW4gaWYgbm90IGFuIEFQRiBwYWNrYWdlIF9idXRfIG9ubHkgaWYgdGhleVxuICAvLyBhcmUgbmFtZWQ/XG4gIGNvbnN0IG5hbWVkU291cmNlcyA9IGdldE5nQXBmU2NyaXB0cyhwa2cpO1xuICBjb25zdCBkZXBzID0gW3BrZ10uY29uY2F0KHBrZy5fZGVwZW5kZW5jaWVzLmZpbHRlcihkZXAgPT4gZGVwICE9PSBwa2cgJiYgIWRlcC5faXNOZXN0ZWQpKTtcblxuICBsZXQgbmFtZWRTb3VyY2VzU3RhcmxhcmsgPSAnJztcbiAgaWYgKG5hbWVkU291cmNlcy5sZW5ndGgpIHtcbiAgICBuYW1lZFNvdXJjZXNTdGFybGFyayA9IGBcbiAgICAjIHN1YnNldCBvZiBzcmNzIHRoYXQgYXJlIGphdmFzY3JpcHQgbmFtZWQtVU1EIG9yIG5hbWVkLUFNRCBzY3JpcHRzXG4gICAgbmFtZWRfc291cmNlcyA9IFtcbiAgICAgICAgJHtuYW1lZFNvdXJjZXMubWFwKChmOiBzdHJpbmcpID0+IGBcIi8vOm5vZGVfbW9kdWxlcy8ke3BrZy5fZGlyfS8ke2Z9XCIsYCkuam9pbignXFxuICAgICAgICAnKX1cbiAgICBdLGA7XG4gIH1cblxuICBsZXQgc3Jjc1N0YXJsYXJrID0gJyc7XG4gIGlmIChzb3VyY2VzLmxlbmd0aCkge1xuICAgIHNyY3NTdGFybGFyayA9IGBcbiAgICAjICR7cGtnLl9kaXJ9IHBhY2thZ2UgZmlsZXMgKGFuZCBmaWxlcyBpbiBuZXN0ZWQgbm9kZV9tb2R1bGVzKVxuICAgIHNyY3MgPSBbXG4gICAgICAgICR7c291cmNlcy5tYXAoKGY6IHN0cmluZykgPT4gYFwiLy86bm9kZV9tb2R1bGVzLyR7cGtnLl9kaXJ9LyR7Zn1cIixgKS5qb2luKCdcXG4gICAgICAgICcpfVxuICAgIF0sYDtcbiAgfVxuXG4gIGxldCBkZXBzU3RhcmxhcmsgPSAnJztcbiAgaWYgKGRlcHMubGVuZ3RoKSB7XG4gICAgY29uc3QgbGlzdCA9IGRlcHMubWFwKGRlcCA9PiBgXCIvLyR7ZGVwLl9kaXJ9OiR7ZGVwLl9uYW1lfV9fY29udGVudHNcIixgKS5qb2luKCdcXG4gICAgICAgICcpO1xuICAgIGRlcHNTdGFybGFyayA9IGBcbiAgICAjIGZsYXR0ZW5lZCBsaXN0IG9mIGRpcmVjdCBhbmQgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMgaG9pc3RlZCB0byByb290IGJ5IHRoZSBwYWNrYWdlIG1hbmFnZXJcbiAgICBkZXBzID0gW1xuICAgICAgICAke2xpc3R9XG4gICAgXSxgO1xuICB9XG5cbiAgbGV0IGR0c1N0YXJsYXJrID0gJyc7XG4gIGlmIChkdHNTb3VyY2VzLmxlbmd0aCkge1xuICAgIGR0c1N0YXJsYXJrID0gYFxuICAgICMgJHtwa2cuX2Rpcn0gcGFja2FnZSBkZWNsYXJhdGlvbiBmaWxlcyAoYW5kIGRlY2xhcmF0aW9uIGZpbGVzIGluIG5lc3RlZCBub2RlX21vZHVsZXMpXG4gICAgc3JjcyA9IFtcbiAgICAgICAgJHtkdHNTb3VyY2VzLm1hcChmID0+IGBcIi8vOm5vZGVfbW9kdWxlcy8ke3BrZy5fZGlyfS8ke2Z9XCIsYCkuam9pbignXFxuICAgICAgICAnKX1cbiAgICBdLGA7XG4gIH1cblxuICBsZXQgcmVzdWx0ID1cbiAgICAgIGBsb2FkKFwiQGJ1aWxkX2JhemVsX3J1bGVzX25vZGVqcy8vaW50ZXJuYWwvbnBtX2luc3RhbGw6bm9kZV9tb2R1bGVfbGlicmFyeS5iemxcIiwgXCJub2RlX21vZHVsZV9saWJyYXJ5XCIpXG5cbiMgR2VuZXJhdGVkIHRhcmdldHMgZm9yIG5wbSBwYWNrYWdlIFwiJHtwa2cuX2Rpcn1cIlxuJHtwcmludEpzb24ocGtnKX1cblxuZmlsZWdyb3VwKFxuICAgIG5hbWUgPSBcIiR7cGtnLl9uYW1lfV9fZmlsZXNcIiwke3NyY3NTdGFybGFya31cbilcblxubm9kZV9tb2R1bGVfbGlicmFyeShcbiAgICBuYW1lID0gXCIke3BrZy5fbmFtZX1cIixcbiAgICAjIGRpcmVjdCBzb3VyY2VzIGxpc3RlZCBmb3Igc3RyaWN0IGRlcHMgc3VwcG9ydFxuICAgIHNyY3MgPSBbXCI6JHtwa2cuX25hbWV9X19maWxlc1wiXSwke2RlcHNTdGFybGFya31cbilcblxuIyAke3BrZy5fbmFtZX1fX2NvbnRlbnRzIHRhcmdldCBpcyB1c2VkIGFzIGRlcCBmb3IgbWFpbiB0YXJnZXRzIHRvIHByZXZlbnRcbiMgY2lyY3VsYXIgZGVwZW5kZW5jaWVzIGVycm9yc1xubm9kZV9tb2R1bGVfbGlicmFyeShcbiAgICBuYW1lID0gXCIke3BrZy5fbmFtZX1fX2NvbnRlbnRzXCIsXG4gICAgc3JjcyA9IFtcIjoke3BrZy5fbmFtZX1fX2ZpbGVzXCJdLCR7bmFtZWRTb3VyY2VzU3Rhcmxhcmt9XG4pXG5cbiMgJHtwa2cuX25hbWV9X190eXBpbmdzIGlzIHRoZSBzdWJzZXQgb2YgJHtwa2cuX25hbWV9X19jb250ZW50cyB0aGF0IGFyZSBkZWNsYXJhdGlvbnNcbm5vZGVfbW9kdWxlX2xpYnJhcnkoXG4gICAgbmFtZSA9IFwiJHtwa2cuX25hbWV9X190eXBpbmdzXCIsJHtkdHNTdGFybGFya31cbilcblxuYDtcblxuICBsZXQgbWFpbkVudHJ5UG9pbnQgPSByZXNvbHZlUGtnTWFpbkZpbGUocGtnKVxuXG4gIC8vIGFkZCBhbiBgbnBtX3VtZF9idW5kbGVgIHRhcmdldCB0byBnZW5lcmF0ZSBhbiBVTUQgYnVuZGxlIGlmIG9uZSBkb2VzXG4gIC8vIG5vdCBleGlzdHNcbiAgaWYgKG1haW5FbnRyeVBvaW50ICYmICFmaW5kRmlsZShwa2csIGAke3BrZy5fbmFtZX0udW1kLmpzYCkpIHtcbiAgICByZXN1bHQgKz1cbiAgICAgICAgYGxvYWQoXCJAYnVpbGRfYmF6ZWxfcnVsZXNfbm9kZWpzLy9pbnRlcm5hbC9ucG1faW5zdGFsbDpucG1fdW1kX2J1bmRsZS5iemxcIiwgXCJucG1fdW1kX2J1bmRsZVwiKVxuXG5ucG1fdW1kX2J1bmRsZShcbiAgICBuYW1lID0gXCIke3BrZy5fbmFtZX1fX3VtZFwiLFxuICAgIHBhY2thZ2VfbmFtZSA9IFwiJHtwa2cuX25hbWV9XCIsXG4gICAgZW50cnlfcG9pbnQgPSBcIi8vOm5vZGVfbW9kdWxlcy8ke3BrZy5fZGlyfS8ke21haW5FbnRyeVBvaW50fVwiLFxuICAgIHBhY2thZ2UgPSBcIjoke3BrZy5fbmFtZX1cIixcbilcblxuYDtcbiAgfVxuXG4gIHJldHVybiByZXN1bHQ7XG59XG5cbmZ1bmN0aW9uIF9maW5kRXhlY3V0YWJsZXMocGtnOiBEZXApIHtcbiAgY29uc3QgZXhlY3V0YWJsZXMgPSBuZXcgTWFwKCk7XG5cbiAgLy8gRm9yIHJvb3QgcGFja2FnZXMsIHRyYW5zZm9ybSB0aGUgcGtnLmJpbiBlbnRyaWVzXG4gIC8vIGludG8gYSBuZXcgTWFwIGNhbGxlZCBfZXhlY3V0YWJsZXNcbiAgLy8gTk9URTogd2UgZG8gdGhpcyBvbmx5IGZvciBub24tZW1wdHkgYmluIHBhdGhzXG4gIGlmIChpc1ZhbGlkQmluUGF0aChwa2cuYmluKSkge1xuICAgIGlmICghcGtnLl9pc05lc3RlZCkge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocGtnLmJpbikpIHtcbiAgICAgICAgaWYgKHBrZy5iaW4ubGVuZ3RoID09IDEpIHtcbiAgICAgICAgICBleGVjdXRhYmxlcy5zZXQocGtnLl9kaXIsIGNsZWFudXBCaW5QYXRoKHBrZy5iaW5bMF0pKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBzaG91bGQgbm90IGhhcHBlbiwgYnV0IGlnbm9yZSBpdCBpZiBwcmVzZW50XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHBrZy5iaW4gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGV4ZWN1dGFibGVzLnNldChwa2cuX2RpciwgY2xlYW51cEJpblBhdGgocGtnLmJpbikpO1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgcGtnLmJpbiA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgZm9yIChsZXQga2V5IGluIHBrZy5iaW4pIHtcbiAgICAgICAgICBpZiAoaXNWYWxpZEJpblBhdGhTdHJpbmdWYWx1ZShwa2cuYmluW2tleV0pKSB7XG4gICAgICAgICAgICBleGVjdXRhYmxlcy5zZXQoa2V5LCBjbGVhbnVwQmluUGF0aChwa2cuYmluW2tleV0pKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhlY3V0YWJsZXM7XG59XG5cbi8vIEhhbmRsZSBhZGRpdGlvbmFsQXR0cmlidXRlcyBvZiBmb3JtYXQ6XG4vLyBgYGBcbi8vIFwiYmF6ZWxCaW5cIjoge1xuLy8gICBcIm5nYy13cmFwcGVkXCI6IHtcbi8vICAgICBcImFkZGl0aW9uYWxBdHRyaWJ1dGVzXCI6IHtcbi8vICAgICAgIFwiY29uZmlndXJhdGlvbl9lbnZfdmFyc1wiOiBcIltcXFwiY29tcGlsZVxcXCJdXCJcbi8vICAgfVxuLy8gfSxcbi8vIGBgYFxuZnVuY3Rpb24gYWRkaXRpb25hbEF0dHJpYnV0ZXMocGtnOiBEZXAsIG5hbWU6IHN0cmluZykge1xuICBsZXQgYWRkaXRpb25hbEF0dHJpYnV0ZXMgPSAnJztcbiAgaWYgKHBrZy5iYXplbEJpbiAmJiBwa2cuYmF6ZWxCaW5bbmFtZV0gJiYgcGtnLmJhemVsQmluW25hbWVdLmFkZGl0aW9uYWxBdHRyaWJ1dGVzKSB7XG4gICAgY29uc3QgYXR0cnMgPSBwa2cuYmF6ZWxCaW5bbmFtZV0uYWRkaXRpb25hbEF0dHJpYnV0ZXM7XG4gICAgZm9yIChjb25zdCBhdHRyTmFtZSBvZiBPYmplY3Qua2V5cyhhdHRycykpIHtcbiAgICAgIGNvbnN0IGF0dHJWYWx1ZSA9IGF0dHJzW2F0dHJOYW1lXTtcbiAgICAgIGFkZGl0aW9uYWxBdHRyaWJ1dGVzICs9IGBcXG4gICAgJHthdHRyTmFtZX0gPSAke2F0dHJWYWx1ZX0sYDtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFkZGl0aW9uYWxBdHRyaWJ1dGVzO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgcGtnLCByZXR1cm4gdGhlIHNreWxhcmsgbm9kZWpzX2JpbmFyeSB0YXJnZXRzIGZvciB0aGUgcGFja2FnZS5cbiAqL1xuZnVuY3Rpb24gcHJpbnRQYWNrYWdlQmluKHBrZzogRGVwKSB7XG4gIGxldCByZXN1bHQgPSAnJztcbiAgY29uc3QgZXhlY3V0YWJsZXMgPSBfZmluZEV4ZWN1dGFibGVzKHBrZyk7XG4gIGlmIChleGVjdXRhYmxlcy5zaXplKSB7XG4gICAgcmVzdWx0ID0gYGxvYWQoXCJAYnVpbGRfYmF6ZWxfcnVsZXNfbm9kZWpzLy86aW5kZXguYnpsXCIsIFwibm9kZWpzX2JpbmFyeVwiKVxuXG5gO1xuICAgIGNvbnN0IGRhdGEgPSBbYC8vJHtwa2cuX2Rpcn06JHtwa2cuX25hbWV9YF07XG4gICAgaWYgKHBrZy5fZHluYW1pY0RlcGVuZGVuY2llcykge1xuICAgICAgZGF0YS5wdXNoKC4uLnBrZy5fZHluYW1pY0RlcGVuZGVuY2llcyk7XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbbmFtZSwgcGF0aF0gb2YgZXhlY3V0YWJsZXMuZW50cmllcygpKSB7XG4gICAgICByZXN1bHQgKz0gYCMgV2lyZSB1cCB0aGUgXFxgYmluXFxgIGVudHJ5IFxcYCR7bmFtZX1cXGBcbm5vZGVqc19iaW5hcnkoXG4gICAgbmFtZSA9IFwiJHtuYW1lfVwiLFxuICAgIGVudHJ5X3BvaW50ID0gXCIvLzpub2RlX21vZHVsZXMvJHtwa2cuX2Rpcn0vJHtwYXRofVwiLFxuICAgIGluc3RhbGxfc291cmNlX21hcF9zdXBwb3J0ID0gRmFsc2UsXG4gICAgZGF0YSA9IFske2RhdGEubWFwKHAgPT4gYFwiJHtwfVwiYCkuam9pbignLCAnKX1dLCR7YWRkaXRpb25hbEF0dHJpYnV0ZXMocGtnLCBuYW1lKX1cbilcblxuYDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBwcmludEluZGV4QnpsKHBrZzogRGVwKSB7XG4gIGxldCByZXN1bHQgPSAnJztcbiAgY29uc3QgZXhlY3V0YWJsZXMgPSBfZmluZEV4ZWN1dGFibGVzKHBrZyk7XG4gIGlmIChleGVjdXRhYmxlcy5zaXplKSB7XG4gICAgcmVzdWx0ID0gYGxvYWQoXCJAYnVpbGRfYmF6ZWxfcnVsZXNfbm9kZWpzLy86aW5kZXguYnpsXCIsIFwibm9kZWpzX2JpbmFyeVwiLCBcIm5wbV9wYWNrYWdlX2JpblwiKVxuXG5gO1xuICAgIGNvbnN0IGRhdGEgPSBbYEAke1dPUktTUEFDRX0vLyR7cGtnLl9kaXJ9OiR7cGtnLl9uYW1lfWBdO1xuICAgIGlmIChwa2cuX2R5bmFtaWNEZXBlbmRlbmNpZXMpIHtcbiAgICAgIGRhdGEucHVzaCguLi5wa2cuX2R5bmFtaWNEZXBlbmRlbmNpZXMpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgW25hbWUsIHBhdGhdIG9mIGV4ZWN1dGFibGVzLmVudHJpZXMoKSkge1xuICAgICAgcmVzdWx0ID0gYCR7cmVzdWx0fVxuXG4jIEdlbmVyYXRlZCBoZWxwZXIgbWFjcm8gdG8gY2FsbCAke25hbWV9XG5kZWYgJHtuYW1lLnJlcGxhY2UoLy0vZywgJ18nKX0oKiprd2FyZ3MpOlxuICAgIG91dHB1dF9kaXIgPSBrd2FyZ3MucG9wKFwib3V0cHV0X2RpclwiLCBGYWxzZSlcbiAgICBpZiBcIm91dHNcIiBpbiBrd2FyZ3Mgb3Igb3V0cHV0X2RpcjpcbiAgICAgICAgbnBtX3BhY2thZ2VfYmluKHRvb2wgPSBcIkAke1dPUktTUEFDRX0vLyR7cGtnLl9kaXJ9L2Jpbjoke1xuICAgICAgICAgIG5hbWV9XCIsIG91dHB1dF9kaXIgPSBvdXRwdXRfZGlyLCAqKmt3YXJncylcbiAgICBlbHNlOlxuICAgICAgICBub2RlanNfYmluYXJ5KFxuICAgICAgICAgICAgZW50cnlfcG9pbnQgPSBcIkAke1dPUktTUEFDRX0vLzpub2RlX21vZHVsZXMvJHtwa2cuX2Rpcn0vJHtwYXRofVwiLFxuICAgICAgICAgICAgaW5zdGFsbF9zb3VyY2VfbWFwX3N1cHBvcnQgPSBGYWxzZSxcbiAgICAgICAgICAgIGRhdGEgPSBbJHtkYXRhLm1hcChwID0+IGBcIiR7cH1cImApLmpvaW4oJywgJyl9XSArIGt3YXJncy5wb3AoXCJkYXRhXCIsIFtdKSwke1xuICAgICAgICAgIGFkZGl0aW9uYWxBdHRyaWJ1dGVzKHBrZywgbmFtZSl9XG4gICAgICAgICAgICAqKmt3YXJnc1xuICAgICAgICApXG4gIGA7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbnR5cGUgRGVwID0ge1xuICBfZGlyOiBzdHJpbmcsXG4gIF9pc05lc3RlZDogYm9vbGVhbixcbiAgX2RlcGVuZGVuY2llczogRGVwW10sXG4gIF9maWxlczogc3RyaW5nW10sXG4gIFtrOiBzdHJpbmddOiBhbnlcbn1cblxuLyoqXG4gKiBHaXZlbiBhIHNjb3BlLCByZXR1cm4gdGhlIHNreWxhcmsgYG5vZGVfbW9kdWxlX2xpYnJhcnlgIHRhcmdldCBmb3IgdGhlIHNjb3BlLlxuICovXG5mdW5jdGlvbiBwcmludFNjb3BlKHNjb3BlOiBzdHJpbmcsIHBrZ3M6IERlcFtdKSB7XG4gIHBrZ3MgPSBwa2dzLmZpbHRlcihwa2cgPT4gIXBrZy5faXNOZXN0ZWQgJiYgcGtnLl9kaXIuc3RhcnRzV2l0aChgJHtzY29wZX0vYCkpO1xuICBsZXQgZGVwczogRGVwW10gPSBbXTtcbiAgcGtncy5mb3JFYWNoKHBrZyA9PiB7XG4gICAgZGVwcyA9IGRlcHMuY29uY2F0KHBrZy5fZGVwZW5kZW5jaWVzLmZpbHRlcihkZXAgPT4gIWRlcC5faXNOZXN0ZWQgJiYgIXBrZ3MuaW5jbHVkZXMocGtnKSkpO1xuICB9KTtcbiAgLy8gZmlsdGVyIG91dCBkdXBsaWNhdGUgZGVwc1xuICBkZXBzID0gWy4uLnBrZ3MsIC4uLm5ldyBTZXQoZGVwcyldO1xuXG4gIGxldCBzcmNzU3RhcmxhcmsgPSAnJztcbiAgaWYgKGRlcHMubGVuZ3RoKSB7XG4gICAgY29uc3QgbGlzdCA9IGRlcHMubWFwKGRlcCA9PiBgXCIvLyR7ZGVwLl9kaXJ9OiR7ZGVwLl9uYW1lfV9fZmlsZXNcIixgKS5qb2luKCdcXG4gICAgICAgICcpO1xuICAgIHNyY3NTdGFybGFyayA9IGBcbiAgICAjIGRpcmVjdCBzb3VyY2VzIGxpc3RlZCBmb3Igc3RyaWN0IGRlcHMgc3VwcG9ydFxuICAgIHNyY3MgPSBbXG4gICAgICAgICR7bGlzdH1cbiAgICBdLGA7XG4gIH1cblxuICBsZXQgZGVwc1N0YXJsYXJrID0gJyc7XG4gIGlmIChkZXBzLmxlbmd0aCkge1xuICAgIGNvbnN0IGxpc3QgPSBkZXBzLm1hcChkZXAgPT4gYFwiLy8ke2RlcC5fZGlyfToke2RlcC5fbmFtZX1fX2NvbnRlbnRzXCIsYCkuam9pbignXFxuICAgICAgICAnKTtcbiAgICBkZXBzU3RhcmxhcmsgPSBgXG4gICAgIyBmbGF0dGVuZWQgbGlzdCBvZiBkaXJlY3QgYW5kIHRyYW5zaXRpdmUgZGVwZW5kZW5jaWVzIGhvaXN0ZWQgdG8gcm9vdCBieSB0aGUgcGFja2FnZSBtYW5hZ2VyXG4gICAgZGVwcyA9IFtcbiAgICAgICAgJHtsaXN0fVxuICAgIF0sYDtcbiAgfVxuXG4gIHJldHVybiBgbG9hZChcIkBidWlsZF9iYXplbF9ydWxlc19ub2RlanMvL2ludGVybmFsL25wbV9pbnN0YWxsOm5vZGVfbW9kdWxlX2xpYnJhcnkuYnpsXCIsIFwibm9kZV9tb2R1bGVfbGlicmFyeVwiKVxuXG4jIEdlbmVyYXRlZCB0YXJnZXQgZm9yIG5wbSBzY29wZSAke3Njb3BlfVxubm9kZV9tb2R1bGVfbGlicmFyeShcbiAgICBuYW1lID0gXCIke3Njb3BlfVwiLCR7c3Jjc1N0YXJsYXJrfSR7ZGVwc1N0YXJsYXJrfVxuKVxuXG5gO1xufVxuIl19 \ No newline at end of file diff --git a/internal/npm_install/generate_build_file.ts b/internal/npm_install/generate_build_file.ts index 85d5a85381..cf30ab39e6 100644 --- a/internal/npm_install/generate_build_file.ts +++ b/internal/npm_install/generate_build_file.ts @@ -882,15 +882,15 @@ function printPackage(pkg: Dep) { const dtsSources = filterFiles(pkg._files, ['.d.ts']); // TODO(gmagolan): add UMD & AMD scripts to scripts even if not an APF package _but_ only if they // are named? - const scripts = getNgApfScripts(pkg); + const namedSources = getNgApfScripts(pkg); const deps = [pkg].concat(pkg._dependencies.filter(dep => dep !== pkg && !dep._isNested)); - let scriptStarlark = ''; - if (scripts.length) { - scriptStarlark = ` + let namedSourcesStarlark = ''; + if (namedSources.length) { + namedSourcesStarlark = ` # subset of srcs that are javascript named-UMD or named-AMD scripts - scripts = [ - ${scripts.map((f: string) => `"//:node_modules/${pkg._dir}/${f}",`).join('\n ')} + named_sources = [ + ${namedSources.map((f: string) => `"//:node_modules/${pkg._dir}/${f}",`).join('\n ')} ],`; } @@ -942,7 +942,7 @@ node_module_library( # circular dependencies errors node_module_library( name = "${pkg._name}__contents", - srcs = [":${pkg._name}__files"],${scriptStarlark} + srcs = [":${pkg._name}__files"],${namedSourcesStarlark} ) # ${pkg._name}__typings is the subset of ${pkg._name}__contents that are declarations diff --git a/internal/npm_install/node_module_library.bzl b/internal/npm_install/node_module_library.bzl index 913fc73f29..bd802f6223 100644 --- a/internal/npm_install/node_module_library.bzl +++ b/internal/npm_install/node_module_library.bzl @@ -15,19 +15,15 @@ """Contains the node_module_library which is used by yarn_install & npm_install. """ -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "NodeModuleSources") +load("@build_bazel_rules_nodejs//:declaration_provider.bzl", "DeclarationInfo") +load("@build_bazel_rules_nodejs//:providers.bzl", "transitive_js_named_module_info") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo") def _node_module_library_impl(ctx): workspace = ctx.label.workspace_root.split("/")[1] if ctx.label.workspace_root else ctx.workspace_name - # All files in `srcs` and in `deps` - # TODO(gregmagolan): transitive sources should be collected an aspect to go - # into a NodeModuleSources.transitive_sources - sources = depset(ctx.files.srcs, transitive = [dep.files for dep in ctx.attr.deps]) - - # scripts are a subset of sources that are javascript named-UMD or named-AMD scripts for - # use in rules such as ts_devserver - scripts = depset(ctx.files.scripts) + # sources are all files in srcs plus those in direct & transitive dependencies + sources = depset(ctx.files.srcs) # declarations are a subset of sources that are declaration files declarations = depset([ @@ -42,11 +38,13 @@ def _node_module_library_impl(ctx): ]) # transitive_declarations are all .d.ts files in srcs plus those in direct & transitive dependencies - transitive_declarations = depset(transitive = [declarations]) + transitive_declarations = declarations for dep in ctx.attr.deps: - if hasattr(dep, "typescript"): - transitive_declarations = depset(transitive = [transitive_declarations, dep.typescript.transitive_declarations]) + if DeclarationInfo in dep: + transitive_declarations = depset(transitive = [transitive_declarations, dep[DeclarationInfo].transitive_declarations]) + if NodeModuleInfo in dep: + sources = depset(transitive = [sources, dep[NodeModuleInfo].sources]) return struct( typescript = struct( @@ -66,13 +64,17 @@ def _node_module_library_impl(ctx): files = sources, ), NodeModuleInfo( - workspace = workspace, - ), - NodeModuleSources( sources = sources, - scripts = scripts, workspace = workspace, ), + DeclarationInfo( + declarations = declarations, + transitive_declarations = transitive_declarations, + ), + transitive_js_named_module_info( + sources = depset(ctx.files.named_sources), + deps = ctx.attr.deps, + ), ], ) @@ -83,8 +85,8 @@ node_module_library = rule( doc = "The list of files that comprise the package", allow_files = True, ), - "scripts": attr.label_list( - doc = "A subset of srcs that are javascript named-UMD or named-AMD scripts for use in rules such as ts_devserver", + "named_sources": attr.label_list( + doc = "A subset of srcs that are javascript named-UMD or named-AMD for use in rules such as ts_devserver", allow_files = True, ), "deps": attr.label_list( diff --git a/internal/npm_install/npm_umd_bundle.bzl b/internal/npm_install/npm_umd_bundle.bzl index a62c7129bb..1ef82007c4 100644 --- a/internal/npm_install/npm_umd_bundle.bzl +++ b/internal/npm_install/npm_umd_bundle.bzl @@ -17,7 +17,7 @@ For use by yarn_install and npm_install. Not meant to be part of the public API. """ -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleSources", "collect_node_modules_aspect") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") def _npm_umd_bundle(ctx): if len(ctx.attr.entry_point.files.to_list()) != 1: @@ -33,7 +33,7 @@ def _npm_umd_bundle(ctx): args.add(output.path) args.add_joined(ctx.attr.excluded, join_with = ",") - sources = ctx.attr.package[NodeModuleSources].sources.to_list() + sources = ctx.attr.package[NodeModuleInfo].sources.to_list() # Only pass .js and package.json files as inputs to browserify. # The latter is required for module resolution in some cases. @@ -91,7 +91,7 @@ This target would be then be used instead of the generated `@npm//typeorm:typeor "package": attr.label( doc = """The npm package target""", mandatory = True, - aspects = [collect_node_modules_aspect], + aspects = [node_modules_aspect], ), "_browserify_wrapped": attr.label( executable = True, diff --git a/internal/npm_install/test/golden/@angular/core/BUILD.bazel.golden b/internal/npm_install/test/golden/@angular/core/BUILD.bazel.golden index 336aa504e7..bf1c2c036f 100644 --- a/internal/npm_install/test/golden/@angular/core/BUILD.bazel.golden +++ b/internal/npm_install/test/golden/@angular/core/BUILD.bazel.golden @@ -677,7 +677,7 @@ node_module_library( node_module_library( name = "core__contents", srcs = [":core__files"], - scripts = [ + named_sources = [ "//:node_modules/@angular/core/bundles/core-testing.umd.js", "//:node_modules/@angular/core/bundles/core.umd.js", ], diff --git a/internal/npm_package/npm_package.bzl b/internal/npm_package/npm_package.bzl index 0cbf203781..8e512dcf87 100644 --- a/internal/npm_package/npm_package.bzl +++ b/internal/npm_package/npm_package.bzl @@ -6,7 +6,8 @@ If all users of your library code use Bazel, they should just add your library to the `deps` of one of their targets. """ -load("//internal/common:sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//:declaration_provider.bzl", "DeclarationInfo") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") # Takes a depset of files and returns a corresponding list of file paths without any files # that aren't part of the specified package path. Also include files from external repositories @@ -95,30 +96,28 @@ def create_package(ctx, deps_sources, nested_packages): return package_dir def _npm_package(ctx): - deps_sources = depset() + sources_depsets = [] + for dep in ctx.attr.deps: - transitive = [ - deps_sources, - # Collect whatever is in the "data" - dep.data_runfiles.files, - ] - - if hasattr(dep, "node_sources"): - # For JavaScript-producing rules, gather up the devmode Node.js sources - transitive.append(dep.node_sources) - else: - # For standalone Output File Targets (aspects not invoked on these) - transitive.append(dep.files) + # Collect whatever is in the "data" + sources_depsets.append(dep.data_runfiles.files) + + # Only collect DefaultInfo files (not transitive) + sources_depsets.append(dep.files) + + # All direct & transitive JavaScript-producing deps + # TODO: switch to JSModuleInfo when it is available + if JSNamedModuleInfo in dep: + sources_depsets.append(dep[JSNamedModuleInfo].sources) - # ts_library doesn't include .d.ts outputs in the runfiles - # see comment in rules_typescript/internal/common/compilation.bzl - if hasattr(dep, "typescript"): - transitive.append(dep.typescript.transitive_declarations) + # Include all transitive declerations + if DeclarationInfo in dep: + sources_depsets.append(dep[DeclarationInfo].transitive_declarations) - deps_sources = depset(transitive = transitive) + sources = depset(transitive = sources_depsets) # Note: to_list() should be called once per rule! - package_dir = create_package(ctx, deps_sources.to_list(), ctx.files.packages) + package_dir = create_package(ctx, sources.to_list(), ctx.files.packages) return [DefaultInfo( files = depset([package_dir]), @@ -154,7 +153,6 @@ NPM_PACKAGE_ATTRS = { ), "deps": attr.label_list( doc = """Other targets which produce files that should be included in the package, such as `rollup_bundle`""", - aspects = [sources_aspect], allow_files = True, ), "_packager": attr.label( diff --git a/internal/npm_package/test/BUILD.bazel b/internal/npm_package/test/BUILD.bazel index a7d6513883..bfe1e8ad93 100644 --- a/internal/npm_package/test/BUILD.bazel +++ b/internal/npm_package/test/BUILD.bazel @@ -1,6 +1,6 @@ load("@build_bazel_rules_nodejs//:index.bzl", "npm_package") load("@npm_bazel_jasmine//:index.from_src.bzl", "jasmine_node_test") -load("//internal/common:typescript_mock_lib.bzl", "mock_typescript_lib") +load("@npm_bazel_typescript//:index.from_src.bzl", "ts_library") load("//third_party/github.com/bazelbuild/bazel-skylib:rules/write_file.bzl", "write_file") write_file( @@ -9,12 +9,9 @@ write_file( content = ["a_dep content"], ) -mock_typescript_lib( +ts_library( name = "ts_library", - srcs = [ - "foo.d.ts", - "foo.js", - ], + srcs = ["foo.ts"], data = ["data.json"], ) diff --git a/internal/npm_package/test/foo.d.ts b/internal/npm_package/test/foo.d.ts deleted file mode 100644 index 425b80f244..0000000000 --- a/internal/npm_package/test/foo.d.ts +++ /dev/null @@ -1 +0,0 @@ -export const a: string; diff --git a/internal/npm_package/test/foo.js b/internal/npm_package/test/foo.js deleted file mode 100644 index ca6a755661..0000000000 --- a/internal/npm_package/test/foo.js +++ /dev/null @@ -1 +0,0 @@ -export const a = ''; diff --git a/internal/npm_package/test/foo.ts b/internal/npm_package/test/foo.ts new file mode 100644 index 0000000000..db233fb40c --- /dev/null +++ b/internal/npm_package/test/foo.ts @@ -0,0 +1 @@ +export const a: string = ''; diff --git a/internal/npm_package/test/npm_package.spec.js b/internal/npm_package/test/npm_package.spec.js index cb5d8a4356..2d2c140fed 100644 --- a/internal/npm_package/test/npm_package.spec.js +++ b/internal/npm_package/test/npm_package.spec.js @@ -22,10 +22,10 @@ describe('npm_package srcs', () => { expect(read('dependent_file')).toEqual('dependent_file content'); }); it('copies js files from ts_library', () => { - expect(read('foo.js')).toEqual('export const a = \'\';'); + expect(read('foo.js')).toContain('exports.a = \'\';'); }); it('copies declaration files from ts_library', () => { - expect(read('foo.d.ts')).toEqual('export const a: string;'); + expect(read('foo.d.ts')).toContain('export declare const a: string;'); }); it('copies data dependencies', () => { expect(read('data.json')).toEqual('[]'); diff --git a/internal/rollup/rollup_bundle.bzl b/internal/rollup/rollup_bundle.bzl index bbffa23185..fa662b7c03 100644 --- a/internal/rollup/rollup_bundle.bzl +++ b/internal/rollup/rollup_bundle.bzl @@ -18,7 +18,7 @@ The versions of Rollup and terser are controlled by the Bazel toolchain. You do not need to install them into your project. """ -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleSources", "collect_node_modules_aspect") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") load("//internal/common:collect_es6_sources.bzl", _collect_es2015_sources = "collect_es6_sources") load("//internal/common:module_mappings.bzl", "get_module_mappings") @@ -64,8 +64,8 @@ def _compute_node_modules_root(ctx): """ node_modules_root = None if ctx.attr.node_modules: - if NodeModuleSources in ctx.attr.node_modules: - node_modules_root = "/".join(["external", ctx.attr.node_modules[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in ctx.attr.node_modules: + node_modules_root = "/".join(["external", ctx.attr.node_modules[NodeModuleInfo].workspace, "node_modules"]) elif ctx.files.node_modules: # ctx.files.node_modules is not an empty list node_modules_root = "/".join([f for f in [ @@ -74,8 +74,8 @@ def _compute_node_modules_root(ctx): "node_modules", ] if f]) for d in ctx.attr.deps: - if NodeModuleSources in d: - possible_root = "/".join(["external", d[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in d: + possible_root = "/".join(["external", d[NodeModuleInfo].workspace, "node_modules"]) if not node_modules_root: node_modules_root = possible_root elif node_modules_root != possible_root: @@ -210,14 +210,15 @@ def _run_rollup(ctx, sources, config, output, map_output = None): args.add_joined(["%s:%s" % g for g in ctx.attr.globals.items()], join_with = ",") direct_inputs = [config] - direct_inputs += _filter_js_inputs(ctx.files.node_modules) + if hasattr(ctx.attr, "node_modules"): + direct_inputs += _filter_js_inputs(ctx.files.node_modules) # Also include files from npm fine grained deps as inputs. - # These deps are identified by the NodeModuleSources provider. + # These deps are identified by the NodeModuleInfo provider. for d in ctx.attr.deps: - if NodeModuleSources in d: + if NodeModuleInfo in d: # Note: we can't avoid calling .to_list() on sources - direct_inputs += _filter_js_inputs(d[NodeModuleSources].sources.to_list()) + direct_inputs += _filter_js_inputs(d[NodeModuleInfo].sources.to_list()) if ctx.file.license_banner: direct_inputs += [ctx.file.license_banner] @@ -569,7 +570,7 @@ def _rollup_bundle(ctx): # If users are in a different repo and load the aspect themselves, they will create # different Provider symbols (e.g. NodeModuleInfo) and we won't find them. # So users must use these symbols that are load'ed in rules_nodejs. -ROLLUP_DEPS_ASPECTS = [rollup_module_mappings_aspect, collect_node_modules_aspect] +ROLLUP_DEPS_ASPECTS = [rollup_module_mappings_aspect, node_modules_aspect] ROLLUP_ATTRS = { "srcs": attr.label_list( diff --git a/packages/jasmine/docs/BUILD.bazel b/packages/jasmine/docs/BUILD.bazel index 556c0544f7..0dd1a0fd2e 100644 --- a/packages/jasmine/docs/BUILD.bazel +++ b/packages/jasmine/docs/BUILD.bazel @@ -34,6 +34,7 @@ stardoc( # ``` "//internal/common:bzl", "//internal/node:bzl", + "//:bzl", ], ) diff --git a/packages/karma/docs/BUILD.bazel b/packages/karma/docs/BUILD.bazel index 6cbcd6523f..1b6b13964f 100644 --- a/packages/karma/docs/BUILD.bazel +++ b/packages/karma/docs/BUILD.bazel @@ -35,6 +35,7 @@ stardoc( # ``` "//internal/common:bzl", "//internal/js_library:bzl", + "//:bzl", ], ) diff --git a/packages/karma/src/karma_web_test.bzl b/packages/karma/src/karma_web_test.bzl index c7f2c8c385..dc1d89255b 100644 --- a/packages/karma/src/karma_web_test.bzl +++ b/packages/karma/src/karma_web_test.bzl @@ -13,7 +13,8 @@ # limitations under the License. "Unit testing with Karma" -load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") load("@build_bazel_rules_nodejs//internal/js_library:js_library.bzl", "write_amd_names_shim") load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite") load("@io_bazel_rules_webtesting//web/internal:constants.bzl", "DEFAULT_WRAPPED_TEST_TAGS") @@ -50,7 +51,7 @@ KARMA_GENERIC_WEB_TEST_ATTRS = dict(COMMON_WEB_TEST_ATTRS, **{ These should be a list of targets which produce JavaScript such as `ts_library`. The files will be loaded in the same order they are declared by that rule.""", allow_files = True, - aspects = [sources_aspect], + aspects = [node_modules_aspect], ), "_conf_tmpl": attr.label( default = Label(_CONF_TMPL), @@ -65,7 +66,6 @@ KARMA_WEB_TEST_ATTRS = dict(KARMA_GENERIC_WEB_TEST_ATTRS, **{ certain attributes of this configuration file. Attributes that are overridden will be outputted to the test log.""", allow_single_file = True, - aspects = [sources_aspect], ), }) @@ -92,11 +92,15 @@ def _write_karma_config(ctx, files, amd_names_shim): sibling = ctx.outputs.executable, ) - config_file = "" - if hasattr(ctx.file, "config_file"): - config_file = ctx.file.config_file - if hasattr(ctx.attr.config_file, "typescript"): - config_file = ctx.attr.config_file.typescript.es5_sources.to_list()[0] + config_file = None + + # Check for config_file since ts_web_test does not have this attribute + if hasattr(ctx.attr, "config_file") and ctx.attr.config_file: + # TODO: switch to JSModuleInfo when it is available + if JSNamedModuleInfo in ctx.attr.config_file: + config_file = ctx.attr.config_file[JSNamedModuleInfo].sources.to_list()[0] + else: + config_file = ctx.file.config_file # The files in the bootstrap attribute come before the require.js support. # Note that due to frameworks = ['jasmine'], a few scripts will come before @@ -129,19 +133,20 @@ def _write_karma_config(ctx, files, amd_names_shim): # Next we load the "runtime_deps" which we expect to contain named AMD modules # Thus they should come after the require.js script, but before any srcs or deps runtime_files = [] - for d in ctx.attr.runtime_deps: - if not hasattr(d, "typescript"): + for dep in ctx.attr.runtime_deps: + if not JSNamedModuleInfo in dep: # Workaround https://github.com/bazelbuild/rules_nodejs/issues/57 # We should allow any JS source as long as it yields something that # can be loaded by require.js fail("labels in runtime_deps must be created by ts_library") - for src in d.typescript.es5_sources.to_list(): + for src in dep[JSNamedModuleInfo].sources.to_list(): runtime_files.append(_to_manifest_path(ctx, src)) # Finally we load the user's srcs and deps user_entries = [ _to_manifest_path(ctx, f) for f in files.to_list() + if f.path.endswith(".js") ] # Expand static_files paths to runfiles for config @@ -187,19 +192,25 @@ def run_karma_web_test(ctx): Returns: The runfiles for the generated action. """ - files = depset(ctx.files.srcs) - for d in ctx.attr.deps + ctx.attr.runtime_deps: - has_node_sources = hasattr(d, "node_sources") - has_dev_scripts = hasattr(d, "dev_scripts") - if has_node_sources: - files = depset(transitive = [files, d.node_sources]) - if has_dev_scripts: - files = depset(transitive = [files, d.dev_scripts]) - if not has_node_sources and not has_dev_scripts and hasattr(d, "files"): - # These are Javascript files directly specified in "deps". - # They are not collected by `sources_aspect` due to the absence of - # `deps` attr. These files must be in named AMD format. - files = depset(transitive = [files, d.files]) + files_depsets = [depset(ctx.files.srcs)] + for dep in ctx.attr.deps + ctx.attr.runtime_deps: + if JSNamedModuleInfo in dep: + files_depsets.append(dep[JSNamedModuleInfo].sources) + if not JSNamedModuleInfo in dep and not NodeModuleInfo in dep and hasattr(dep, "files"): + # These are javascript files provided by DefaultInfo from a direct + # dep that has no JSNamedModuleInfo provider or NodeModuleInfo + # provider (not an npm dep). These files must be in named AMD or named + # UMD format. + files_depsets.append(dep.files) + files = depset(transitive = files_depsets) + + # Also include files from npm fine grained deps as inputs. + # These deps are identified by the NodeModuleInfo provider. + node_modules_depsets = [] + for dep in ctx.attr.deps + ctx.attr.runtime_deps: + if NodeModuleInfo in dep: + node_modules_depsets.append(dep[NodeModuleInfo].sources) + node_modules = depset(transitive = node_modules_depsets) amd_names_shim = _write_amd_names_shim(ctx) @@ -250,11 +261,14 @@ $KARMA ${{ARGV[@]}} ) config_sources = [] - if hasattr(ctx.file, "config_file"): - if ctx.file.config_file: + + # Check for config_file since ts_web_test does not have this attribute + if hasattr(ctx.attr, "config_file") and ctx.attr.config_file: + # TODO: switch to JSModuleInfo when it is available + if JSNamedModuleInfo in ctx.attr.config_file: + config_sources = ctx.attr.config_file[JSNamedModuleInfo].sources.to_list() + else: config_sources = [ctx.file.config_file] - if hasattr(ctx.attr.config_file, "node_sources"): - config_sources = ctx.attr.config_file.node_sources.to_list() runfiles = [ configuration, @@ -270,7 +284,7 @@ $KARMA ${{ARGV[@]}} return ctx.runfiles( files = runfiles, - transitive_files = files, + transitive_files = depset(transitive = [files, node_modules]), ).merge(ctx.attr.karma[DefaultInfo].data_runfiles) def _karma_web_test_impl(ctx): diff --git a/packages/karma/src/web_test.bzl b/packages/karma/src/web_test.bzl index 7ebb58b259..23c3433744 100644 --- a/packages/karma/src/web_test.bzl +++ b/packages/karma/src/web_test.bzl @@ -13,7 +13,7 @@ # limitations under the License. "Common web_test attributes" -load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "node_modules_aspect") # Attributes shared by any web_test rule (ts_web_test, karma_web_test, protractor_web_test) COMMON_WEB_TEST_ATTRS = { @@ -35,6 +35,6 @@ COMMON_WEB_TEST_ATTRS = { "deps": attr.label_list( doc = "Other targets which produce JavaScript such as `ts_library`", allow_files = True, - aspects = [sources_aspect], + aspects = [node_modules_aspect], ), } diff --git a/packages/labs/src/protobufjs/ts_proto_library.bzl b/packages/labs/src/protobufjs/ts_proto_library.bzl index dc699945da..34561117cf 100644 --- a/packages/labs/src/protobufjs/ts_proto_library.bzl +++ b/packages/labs/src/protobufjs/ts_proto_library.bzl @@ -14,7 +14,7 @@ "Protocol Buffers" load("@build_bazel_rules_nodejs//:declaration_provider.bzl", "DeclarationInfo") -load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSEcmaScriptModuleInfo", "JSNamedModuleInfo") def _run_pbjs(actions, executable, output_name, proto_files, suffix = ".js", wrap = "amd", amd_name = ""): js_file = actions.declare_file(output_name + suffix) @@ -118,6 +118,9 @@ def _ts_proto_library(ctx): declarations = declarations, transitive_declarations = declarations, ), + JSNamedModuleInfo( + sources = es5_sources, + ), JSEcmaScriptModuleInfo( sources = es6_sources, ), diff --git a/packages/protractor/docs/BUILD.bazel b/packages/protractor/docs/BUILD.bazel index 3d1521037a..f4fba32997 100644 --- a/packages/protractor/docs/BUILD.bazel +++ b/packages/protractor/docs/BUILD.bazel @@ -31,6 +31,7 @@ stardoc( # `@build_bazel_rules_nodejs//foo:bzl` style deps are not found # by the doc generator: # ``` + # Exception in thread "main" java.lang.IllegalStateException: File external/npm_bazel_jasmine/jasmine_node_test.bzl imported '@build_bazel_rules_nodejs//internal/common:devmode_js_sources.bzl', yet internal/common/devmode_js_sources.bzl was not found, even at roots [.]. # ``` "//:bzl", "//internal/common:bzl", diff --git a/packages/protractor/src/protractor_web_test.bzl b/packages/protractor/src/protractor_web_test.bzl index 69dfa02b98..3b8f22c153 100644 --- a/packages/protractor/src/protractor_web_test.bzl +++ b/packages/protractor/src/protractor_web_test.bzl @@ -14,7 +14,8 @@ "Run end-to-end tests with Protractor" load("@build_bazel_rules_nodejs//:index.bzl", "nodejs_binary") -load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") load("@build_bazel_rules_nodejs//internal/common:windows_utils.bzl", "create_windows_native_launcher_script", "is_windows") load("@io_bazel_rules_webtesting//web:web.bzl", "web_test_suite") load("@io_bazel_rules_webtesting//web/internal:constants.bzl", "DEFAULT_WRAPPED_TEST_TAGS") @@ -36,12 +37,25 @@ def _protractor_web_test_impl(ctx): sibling = ctx.outputs.script, ) - files = depset(ctx.files.srcs) - for d in ctx.attr.deps: - if hasattr(d, "node_sources"): - files = depset(transitive = [files, d.node_sources]) - elif hasattr(d, "files"): - files = depset(transitive = [files, d.files]) + files_depsets = [depset(ctx.files.srcs)] + for dep in ctx.attr.deps: + if JSNamedModuleInfo in dep: + files_depsets.append(dep[JSNamedModuleInfo].sources) + if not JSNamedModuleInfo in dep and not NodeModuleInfo in dep and hasattr(dep, "files"): + # These are javascript files provided by DefaultInfo from a direct + # dep that has no JSNamedModuleInfo provider or NodeModuleInfo + # provider (not an npm dep). These files must be in named AMD or named + # UMD format. + files_depsets.append(dep.files) + files = depset(transitive = files_depsets) + + # Also include files from npm fine grained deps as inputs. + # These deps are identified by the NodeModuleInfo provider. + node_modules_depsets = [] + for dep in ctx.attr.deps: + if NodeModuleInfo in dep: + node_modules_depsets.append(dep[NodeModuleInfo].sources) + node_modules = depset(transitive = node_modules_depsets) specs = [ _to_manifest_path(ctx, f) @@ -49,24 +63,26 @@ def _protractor_web_test_impl(ctx): ] configuration_sources = [] - if ctx.file.configuration: - configuration_sources = [ctx.file.configuration] - if hasattr(ctx.attr.configuration, "node_sources"): - configuration_sources = ctx.attr.configuration.node_sources.to_list() - - configuration_file = ctx.file.configuration - if hasattr(ctx.attr.configuration, "typescript"): - configuration_file = ctx.attr.configuration.typescript.es5_sources.to_list()[0] + configuration_file = None + if ctx.attr.configuration: + # TODO: switch to JSModuleInfo when it is available + if JSNamedModuleInfo in ctx.attr.configuration: + configuration_sources = ctx.attr.configuration[JSNamedModuleInfo].sources.to_list() + configuration_file = ctx.attr.configuration[JSNamedModuleInfo].sources.to_list()[0] + else: + configuration_sources = [ctx.file.configuration] + configuration_file = ctx.file.configuration on_prepare_sources = [] - if ctx.file.on_prepare: - on_prepare_sources = [ctx.file.on_prepare] - if hasattr(ctx.attr.on_prepare, "node_sources"): - on_prepare_sources = ctx.attr.on_prepare.node_sources.to_list() - - on_prepare_file = ctx.file.on_prepare - if hasattr(ctx.attr.on_prepare, "typescript"): - on_prepare_file = ctx.attr.on_prepare.typescript.es5_sources.to_list()[0] + on_prepare_file = None + if ctx.attr.on_prepare: + # TODO: switch to JSModuleInfo when it is available + if JSNamedModuleInfo in ctx.attr.on_prepare: + on_prepare_sources = ctx.attr.on_prepare[JSNamedModuleInfo].sources.to_list() + on_prepare_file = ctx.attr.on_prepare[JSNamedModuleInfo].sources.to_list()[0] + else: + on_prepare_sources = [ctx.file.on_prepare] + on_prepare_file = ctx.file.on_prepare ctx.actions.expand_template( output = configuration, @@ -127,7 +143,7 @@ $PROTRACTOR $CONF files = depset([ctx.outputs.script]), runfiles = ctx.runfiles( files = runfiles, - transitive_files = files, + transitive_files = depset(transitive = [files, node_modules]), # Propagate protractor_bin and its runfiles collect_data = True, collect_default = True, @@ -149,7 +165,6 @@ _protractor_web_test = rule( "configuration": attr.label( doc = "Protractor configuration file", allow_single_file = True, - aspects = [sources_aspect], ), "data": attr.label_list( doc = "Runtime dependencies", @@ -159,7 +174,6 @@ _protractor_web_test = rule( If the script exports a function which returns a promise, protractor will wait for the promise to resolve before beginning tests.""", allow_single_file = True, - aspects = [sources_aspect], ), "protractor": attr.label( doc = "Protractor executable target", @@ -176,7 +190,7 @@ _protractor_web_test = rule( "deps": attr.label_list( doc = "Other targets which produce JavaScript such as `ts_library`", allow_files = True, - aspects = [sources_aspect], + aspects = [node_modules_aspect], ), "_conf_tmpl": attr.label( default = Label(_CONF_TMPL), diff --git a/packages/protractor/test/protractor-2/BUILD.bazel b/packages/protractor/test/protractor-2/BUILD.bazel index fb49f3e4ee..5e6ee6fb86 100644 --- a/packages/protractor/test/protractor-2/BUILD.bazel +++ b/packages/protractor/test/protractor-2/BUILD.bazel @@ -1,6 +1,7 @@ -load("@build_bazel_rules_nodejs//:index.bzl", "rollup_bundle") load("@npm//http-server:index.bzl", "http_server") load("@npm_bazel_protractor//:index.from_src.bzl", "protractor_web_test_suite") +load("@npm_bazel_rollup//:index.from_src.bzl", "rollup_bundle") +load("@npm_bazel_terser//:index.from_src.bzl", "terser_minified") load("@npm_bazel_typescript//:index.bzl", "ts_config") load("@npm_bazel_typescript//:index.from_src.bzl", "ts_devserver", "ts_library") @@ -25,16 +26,20 @@ ts_devserver( rollup_bundle( name = "bundle", - enable_code_splitting = False, entry_point = ":app.ts", deps = [":app"], ) +terser_minified( + name = "bundle.min", + src = ":bundle", +) + http_server( name = "prodserver", data = [ "index.html", - ":bundle.min.js", + ":bundle.min", ], # This repeats the default, but is here for coverage # to make sure the generated index.bzl handles it diff --git a/packages/typescript/src/internal/build_defs.bzl b/packages/typescript/src/internal/build_defs.bzl index 76b041445d..01386e28e0 100644 --- a/packages/typescript/src/internal/build_defs.bzl +++ b/packages/typescript/src/internal/build_defs.bzl @@ -14,8 +14,8 @@ "TypeScript compilation" -load("@build_bazel_rules_nodejs//:providers.bzl", "transitive_js_ecma_script_module_info") -load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleSources", "collect_node_modules_aspect") +load("@build_bazel_rules_nodejs//:providers.bzl", "transitive_js_ecma_script_module_info", "transitive_js_named_module_info") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") # pylint: disable=unused-argument # pylint: disable=missing-docstring @@ -46,7 +46,7 @@ def _trim_package_node_modules(package_name): # but wouldn't work for other rules like nodejs_binary def _uses_bazel_managed_node_modules(ctx): # If the user put a filegroup as the node_modules it will have no provider - return NodeModuleSources in ctx.attr.node_modules + return NodeModuleInfo in ctx.attr.node_modules # This function is similar but slightly different than _compute_node_modules_root # in /internal/node/node.bzl. TODO(gregmagolan): consolidate these functions @@ -61,8 +61,8 @@ def _compute_node_modules_root(ctx): """ node_modules_root = None if ctx.attr.node_modules: - if NodeModuleSources in ctx.attr.node_modules: - node_modules_root = "/".join(["external", ctx.attr.node_modules[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in ctx.attr.node_modules: + node_modules_root = "/".join(["external", ctx.attr.node_modules[NodeModuleInfo].workspace, "node_modules"]) elif ctx.files.node_modules: # ctx.files.node_modules is not an empty list node_modules_root = "/".join([f for f in [ @@ -71,8 +71,8 @@ def _compute_node_modules_root(ctx): "node_modules", ] if f]) for d in ctx.attr.deps: - if NodeModuleSources in d: - possible_root = "/".join(["external", d[NodeModuleSources].workspace, "node_modules"]) + if NodeModuleInfo in d: + possible_root = "/".join(["external", d[NodeModuleInfo].workspace, "node_modules"]) if not node_modules_root: node_modules_root = possible_root elif node_modules_root != possible_root: @@ -118,11 +118,11 @@ def _compile_action(ctx, inputs, outputs, tsconfig_file, node_opts, description action_inputs.extend(_filter_ts_inputs(ctx.files.node_modules)) # Also include files from npm fine grained deps as action_inputs. - # These deps are identified by the NodeModuleSources provider. + # These deps are identified by the NodeModuleInfo provider. for d in ctx.attr.deps: - if NodeModuleSources in d: + if NodeModuleInfo in d: # Note: we can't avoid calling .to_list() on sources - action_inputs.extend(_filter_ts_inputs(d[NodeModuleSources].sources.to_list())) + action_inputs.extend(_filter_ts_inputs(d[NodeModuleInfo].sources.to_list())) if ctx.file.tsconfig: action_inputs.append(ctx.file.tsconfig) @@ -275,12 +275,16 @@ def _ts_library_impl(ctx): # See design doc https://docs.google.com/document/d/1ggkY5RqUkVL4aQLYm7esRW978LgX3GUCnQirrk5E1C0/edit# # and issue https://github.com/bazelbuild/rules_nodejs/issues/57 for more details. ts_providers["providers"].extend([ + transitive_js_named_module_info( + sources = ts_providers["typescript"]["es5_sources"], + deps = ctx.attr.deps, + ), transitive_js_ecma_script_module_info( sources = ts_providers["typescript"]["es6_sources"], deps = ctx.attr.deps, ), - # TODO: Add remaining shared JS providers from design doc - # (JSModuleInfo and JSNamedModuleInfo) and remove legacy "typescript" provider + # TODO: Add remaining shared JS provider from design doc + # (JSModuleInfo) and remove legacy "typescript" provider # once it is no longer needed. ]) @@ -412,7 +416,7 @@ either: doc = "If using tsickle, instruct it to translate types to ClosureJS format", ), "deps": attr.label_list( - aspects = DEPS_ASPECTS + [collect_node_modules_aspect], + aspects = DEPS_ASPECTS + [node_modules_aspect], doc = "Compile-time dependencies, typically other ts_library targets", ), }), diff --git a/packages/typescript/src/internal/devserver/ts_devserver.bzl b/packages/typescript/src/internal/devserver/ts_devserver.bzl index 66a80c35b8..64abf34d70 100644 --- a/packages/typescript/src/internal/devserver/ts_devserver.bzl +++ b/packages/typescript/src/internal/devserver/ts_devserver.bzl @@ -14,7 +14,8 @@ "Simple development server" -load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") +load("@build_bazel_rules_nodejs//internal/common:node_module_info.bzl", "NodeModuleInfo", "node_modules_aspect") load( "@build_bazel_rules_nodejs//internal/js_library:js_library.bzl", "write_amd_names_shim", @@ -33,15 +34,25 @@ def _to_manifest_path(ctx, file): return ctx.workspace_name + "/" + file.short_path def _ts_devserver(ctx): - files = depset() - dev_scripts = depset() - for d in ctx.attr.deps: - if hasattr(d, "node_sources"): - files = depset(transitive = [files, d.node_sources]) - elif hasattr(d, "files"): - files = depset(transitive = [files, d.files]) - if hasattr(d, "dev_scripts"): - dev_scripts = depset(transitive = [dev_scripts, d.dev_scripts]) + files_depsets = [] + for dep in ctx.attr.deps: + if JSNamedModuleInfo in dep: + files_depsets.append(dep[JSNamedModuleInfo].sources) + if not JSNamedModuleInfo in dep and not NodeModuleInfo in dep and hasattr(dep, "files"): + # These are javascript files provided by DefaultInfo from a direct + # dep that has no JSNamedModuleInfo provider or NodeModuleInfo + # provider (not an npm dep). These files must be in named AMD or named + # UMD format. + files_depsets.append(dep.files) + files = depset(transitive = files_depsets) + + # Also include files from npm fine grained deps as inputs. + # These deps are identified by the NodeModuleInfo provider. + node_modules_depsets = [] + for dep in ctx.attr.deps: + if NodeModuleInfo in dep: + node_modules_depsets.append(dep[NodeModuleInfo].sources) + node_modules = depset(transitive = node_modules_depsets) if ctx.label.workspace_root: # We need the workspace_name for the target being visited. @@ -59,6 +70,7 @@ def _ts_devserver(ctx): ctx.actions.write(ctx.outputs.manifest, "".join([ workspace_name + "/" + f.short_path + "\n" for f in files.to_list() + if f.path.endswith(".js") ])) amd_names_shim = ctx.actions.declare_file( @@ -75,7 +87,6 @@ def _ts_devserver(ctx): script_files.append(ctx.file._requirejs_script) script_files.append(amd_names_shim) script_files.extend(ctx.files.scripts) - script_files.extend(dev_scripts.to_list()) ctx.actions.write(ctx.outputs.scripts_manifest, "".join([ workspace_name + "/" + f.short_path + "\n" for f in script_files @@ -128,7 +139,7 @@ def _ts_devserver(ctx): files = devserver_runfiles, # We don't expect executable targets to depend on the devserver, but if they do, # they can see the JavaScript code. - transitive_files = depset(ctx.files.data, transitive = [files]), + transitive_files = depset(ctx.files.data, transitive = [files, node_modules]), collect_data = True, collect_default = True, ), @@ -192,7 +203,7 @@ ts_devserver = rule( "deps": attr.label_list( doc = "Targets that produce JavaScript, such as `ts_library`", allow_files = True, - aspects = [sources_aspect], + aspects = [node_modules_aspect], ), "_bash_runfile_helpers": attr.label(default = Label("@bazel_tools//tools/bash/runfiles")), "_injector": attr.label( diff --git a/packages/typescript/test/devmode_consumer/devmode_consumer.bzl b/packages/typescript/test/devmode_consumer/devmode_consumer.bzl index b23a4b421d..ed90e109cf 100644 --- a/packages/typescript/test/devmode_consumer/devmode_consumer.bzl +++ b/packages/typescript/test/devmode_consumer/devmode_consumer.bzl @@ -15,26 +15,23 @@ """Example of a rule that requires es2015 (devmode) inputs. """ -load("@build_bazel_rules_nodejs//internal/common:sources_aspect.bzl", "sources_aspect") +load("@build_bazel_rules_nodejs//:providers.bzl", "JSNamedModuleInfo") def _devmode_consumer(ctx): - files = depset() - - # Since we apply the sources_aspect to our deps below, we can iterate through - # the deps and grab the attribute attached by that aspect, which is called - # "node_sources". - # See https://github.com/bazelbuild/rules_nodejs/blob/master/internal/node.bzl - for d in ctx.attr.deps: - files = depset(transitive = [files, d.node_sources]) + sources_depsets = [] + for dep in ctx.attr.deps: + if JSNamedModuleInfo in dep: + sources_depsets.append(dep[JSNamedModuleInfo].sources) + sources = depset(transitive = sources_depsets) return [DefaultInfo( - files = files, - runfiles = ctx.runfiles(files.to_list()), + files = sources, + runfiles = ctx.runfiles(transitive_files = sources), )] devmode_consumer = rule( implementation = _devmode_consumer, attrs = { - "deps": attr.label_list(aspects = [sources_aspect]), + "deps": attr.label_list(), }, ) diff --git a/providers.bzl b/providers.bzl index 63512fecbe..9c9f5bf0f4 100644 --- a/providers.bzl +++ b/providers.bzl @@ -22,6 +22,51 @@ If users really need to produce both in a single build, they'll need two rules w differing 'debug' attributes. """ +JSNamedModuleInfo = provider( + doc = """JavaScript files whose module name is self-contained. + +For example named AMD/UMD or goog.module format. +These files can be efficiently served with the concatjs bundler. +These outputs should be named "foo.umd.js" +(note that renaming it from "foo.js" doesn't affect the module id) + +Historical note: this was the typescript.es5_sources output. +""", + fields = { + "sources": "depset of direct and transitive JavaScript files and sourcemaps", + }, +) + +def transitive_js_named_module_info(sources, deps = []): + """Constructs a JSNamedModuleInfo including all transitive sources from JSNamedModuleInfo providers in a list of deps. + +Returns a single JSNamedModuleInfo. +""" + return combine_js_named_module_info([JSNamedModuleInfo(sources = sources)] + collect_js_named_module_infos(deps)) + +def combine_js_named_module_info(modules): + """Combines all JavaScript sources and sourcemaps from a list of JSNamedModuleInfo providers. + +Returns a single JSNamedModuleInfo. +""" + sources_depsets = [] + for module in modules: + sources_depsets.extend([module.sources]) + return JSNamedModuleInfo( + sources = depset(transitive = sources_depsets), + ) + +def collect_js_named_module_infos(deps): + """Collects all JSNamedModuleInfo providers from a list of deps. + +Returns a list of JSNamedModuleInfo providers. +""" + modules = [] + for dep in deps: + if JSNamedModuleInfo in dep: + modules.extend([dep[JSNamedModuleInfo]]) + return modules + JSEcmaScriptModuleInfo = provider( doc = """JavaScript files (and sourcemaps) that are intended to be consumed by downstream tooling.